home *** CD-ROM | disk | FTP | other *** search
/ 1,000 Game Levels 2 / 1,000 Game Levels 2.iso / DOSARC / FMAZ21.ZIP / HEXMAZE.C < prev    next >
C/C++ Source or Header  |  1995-04-17  |  96KB  |  2,453 lines

  1. /*
  2.                                FMAZ21 -- Maze Game
  3.  
  4.                               Version 2.1 (4/15/95)
  5.  
  6.  
  7.      Generate and solve mazes on your VGA (or better) display.
  8.  
  9.      The mazes are displayed in three dimensions.
  10.  
  11.      You will be prompted for the number of columns, the tilt, and a random 
  12. number seed. 
  13.  
  14.      While the maze is being generated, a spinning cursor is displayed.
  15.  
  16.      After the maze is displayed, you may use the Home, PgUp, PgDn, End, up 
  17. arrow, and down arrow keys to solve it.  Press "Q" to quit or press "S" to have
  18. the computer solve the maze.
  19.  
  20.      After the maze is solved, you must press some key to continue.
  21.  
  22.      Each maze has exactly one solution that does not involve backtracking
  23. (passing through a doorway more than once).
  24.  
  25.      This program was written by James L. Dean.
  26.  
  27. */
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <math.h>
  31. #include <stdlib.h>
  32. #include <conio.h>
  33. #include <dos.h>
  34. #include <graphics.h>
  35.  
  36. typedef struct corner_record
  37.           {
  38.             int x;
  39.             int y;
  40.           } corner_rec;
  41.  
  42. typedef struct vertex_record
  43.           {
  44.             double x;
  45.             double y;
  46.           } vertex_rec;
  47.  
  48. typedef struct triangle_record
  49.           {
  50.             vertex_rec vertex [3];
  51.           } triangle_rec;
  52.  
  53. typedef struct rectangle_record
  54.           {
  55.             vertex_rec vertex [4];
  56.           } rectangle_rec;
  57.  
  58. typedef struct stack_rec_record
  59.           {
  60.             char index_1;
  61.             int  index_2;
  62.           } stack_rec;
  63.  
  64. #define TRUE  1
  65. #define FALSE 0
  66.  
  67.  
  68. #define GRAPHICS_DRIVER                VGA /* 640x480x16 VGA */
  69. #define GRAPHICS_MODE                VGAHI /* must support red, green, yellow,
  70.                                               and 9 shades of gray */
  71. #define NUM_COLORS                      16
  72. #define TOP_COLOR                       12 /* all but last 3 colors are gray */
  73. #define RECTANGLE_SE_NW_COLOR           10
  74. #define TRIANGLE_SSE_NNW_COLOR           9
  75. #define TRIANGLE_SE_NW_COLOR             8
  76. #define RECTANGLE_W_E_COLOR              7
  77. #define FLOOR_COLOR                      6
  78. #define TRIANGLE_SW_NE_COLOR             5 
  79. #define RECTANGLE_SW_NE_COLOR            4 
  80. #define TRIANGLE_SSW_NNE_COLOR           3
  81. #define BACKOUT_COLOR                   13
  82. #define ADVANCE_COLOR                   14
  83. #define SOLUTION_COLOR                  15
  84. #define WIDTH_OF_GRAPHICS_IN_INCHES      8.0
  85. #define NUM_X_PIXELS                   640
  86. #define WIDTH_OF_GRAPHICS_IN_PIXELS    640
  87. #define HEIGHT_OF_GRAPHICS_IN_INCHES     5.0
  88. #define NUM_Y_PIXELS                   480
  89. #define HEIGHT_OF_GRAPHICS_IN_PIXELS   400  
  90.  
  91. #define RELATIVE_WIDTH_OF_WALL           0.25 /* relative to side of hexagon */
  92. #define RELATIVE_HEIGHT_OF_WALL          1.5  /* relative to side of hexagon */
  93. #define MIN_WALL_LENGTH_IN_PIXELS       12
  94.  
  95. static void           display_quadrilateral(double,double,double,double,double,
  96.                        double,double,double,double,double,double,double,double,
  97.                        double,double,double,double,double,double,double,int);
  98. static void           display_solution(int,char **,double,double,double,double,
  99.                        double,double,double,double);
  100. static void           display_triangle(double,double,double,double,double,
  101.                        double,double,double,double,double,double,double,double,
  102.                        double,double,double,double,int);
  103. static void           draw_line(double,double,double,double,double,double,
  104.                        double,double,double,double,double,double);
  105. static void           free_memory(char ***,char ***,int,stack_rec **);
  106. static void           generate_maze(char *,char **,int,int,stack_rec *,int,int,
  107.                        int);
  108. static void           get_corner(double,double,double,double,double,double,
  109.                        double,double,double,double,double,corner_rec *);
  110. static void           get_cursor(unsigned char *,unsigned char *,
  111.                        unsigned char *,unsigned char *);
  112. static void           get_defaults(char *,int *,double *,char *);
  113. static void           hash(int *,int *,int *,int *,int *,int *,int *,int *);
  114. static void           increment(int *,int *,int *,int *,int *,int *,int *,
  115.                        int *);
  116. static void           let_user_try_to_solve(int *,int,int,char **,char **,
  117.                        double,double,double,double,double,double,double,double);
  118.        int            main(int,char **);
  119. static int            memory_allocated(char ***,char ***,int,int,stack_rec **,
  120.                        int);
  121.        void interrupt new_critical_error_handler(void);
  122.        void interrupt (*old_critical_error_handler)(void);
  123. static void           output_maze(char **,int,int,double,double,double,double,
  124.                        double,double,double,double);
  125. static void           output_rectangle(double,double,double,rectangle_rec *,
  126.                        double,double,double,double,double,int);
  127. static void           output_triangle(double,double,double,triangle_rec *,
  128.                        double,double,double,double,double,int,int);
  129. static void           put_defaults(char *,int,double,char *);
  130. static void           set_cursor_position(unsigned char,unsigned char);
  131. static void           set_cursor_size(unsigned char,unsigned char);
  132. static void           solve_maze(stack_rec *,char **,int *,int *,int,int);
  133. static void           titillate(void);
  134.  
  135. extern unsigned _stklen=0x8000;
  136.  
  137. static unsigned char cursor_column;
  138. static unsigned char cursor_row;
  139. static unsigned char cursor_start;
  140. static unsigned char cursor_stop;
  141. static int           delta_x [6] [720];
  142. static int           delta_y [6] [720];
  143. static int           file_opened;
  144. static double        sqrt_3;
  145. static char          titillator [4] = {'|','/','-','\\'};
  146. static int           titillator_index;
  147.  
  148. int main(
  149.   int  argc,
  150.   char *argv[])
  151.     {
  152.       register int                color_num;
  153.       static   char               **computer_page;
  154.       static   double             cos_tilt;
  155.       static   int                default_num_columns;
  156.       static   char               default_seed [256];
  157.       static   double             default_tilt;
  158.       static   int                ErrorCode;
  159.       static   int                fatal_error;
  160.       static   int                GraphDriver;
  161.       static   int                GraphMode;
  162.       static   char               line [256];
  163.       static   char               *line_ptr;
  164.       static   int                max_num_columns;
  165.       static   int                max_x;
  166.       static   int                max_x_plus_1;
  167.       static   int                max_y;
  168.       static   int                max_y_plus_1;
  169.       static   int                min_num_columns;
  170.       static   int                num_assigned;
  171.       static   int                num_columns;
  172.       static   int                num_rooms_in_maze;
  173.       static   int                num_rows;
  174.       static   struct palettetype palette;
  175.       static   double             pixels_per_x;
  176.       static   double             pixels_per_z;
  177.       static   double             radians;
  178.       static   double             radians_per_degree;
  179.       static   double             rel_dist_of_user_from_screen;
  180.       static   int                response;
  181.       static   char               seed [256];
  182.       static   int                seed_index;
  183.       static   double             sin_tilt;
  184.       static   stack_rec          *stack;
  185.       static   double             tilt;
  186.       static   int                tint;
  187.       static   char               **user_page;
  188.       static   int                user_still_interested;
  189.       static   double             x_max;
  190.       static   double             x_offset;
  191.       static   double             y_max;
  192.  
  193.       fatal_error=FALSE;
  194.       sqrt_3=sqrt(3.0);
  195.       min_num_columns=3;
  196.       max_num_columns=(int) (2.0*(((double) WIDTH_OF_GRAPHICS_IN_PIXELS)
  197.        /((double) MIN_WALL_LENGTH_IN_PIXELS)-2.0
  198.        -((double) RELATIVE_WIDTH_OF_WALL)/sqrt_3)/3.0+1.0);
  199.       if (max_num_columns%2 == 0)
  200.         max_num_columns--;
  201.       if (max_num_columns < 3)
  202.         max_num_columns=3;
  203.       get_defaults(argv[0],&default_num_columns,&default_tilt,&default_seed[0]);
  204.       do
  205.         {
  206.           clrscr();
  207.           printf(
  208. "                              FMAZ21 -- Maze Game\n\n"
  209. "                             Version 2.1 (4/15/95)\n\n\n"
  210. "     Generate and solve mazes on your VGA (or better) display.\n\n"
  211. "     The mazes are displayed in three dimensions.\n\n"
  212. "     To get the value surrounded by [], just press Enter.\n\n");
  213.           do
  214.             {
  215.               printf("     Number of columns (%d to %d, or 0 to exit) [%d]?  ",
  216.                min_num_columns,max_num_columns,default_num_columns);
  217.               fflush(stdin);
  218.               fgets(&line[0],256,stdin);
  219.               line_ptr=&line[0];
  220.               while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  221.                 line_ptr++;
  222.               if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  223.                 num_columns=default_num_columns;
  224.               else
  225.                 {
  226.                   num_assigned=sscanf(line_ptr,"%d",&num_columns);
  227.                   if ((num_assigned == 0) || (num_assigned == EOF))
  228.                     num_columns=-1;
  229.                 }
  230.             }
  231.           while ((num_columns != 0)
  232.           &&     ((num_columns < min_num_columns) 
  233.                || (num_columns > max_num_columns)));
  234.           user_still_interested=num_columns;
  235.           if (user_still_interested)
  236.             {
  237.               printf("\n");
  238.               if (num_columns%2 == 0)
  239.                 num_columns++;
  240.               num_rows=(int) (((((double) HEIGHT_OF_GRAPHICS_IN_INCHES)
  241.                /((double) WIDTH_OF_GRAPHICS_IN_INCHES))
  242.                *(3.0*(((double) num_columns)-1.0)/2.0+2.0
  243.                +((double) RELATIVE_WIDTH_OF_WALL)/sqrt_3)
  244.                -((double) RELATIVE_WIDTH_OF_WALL))/sqrt_3);
  245.               if (num_rows < 2)
  246.                 num_rows=2;
  247.               do
  248.                 {
  249.                   printf("     Tilt (30 to 60 degrees) [%lf]?  ",default_tilt);
  250.                   fflush(stdin);
  251.                   fgets(&line[0],256,stdin);
  252.                   line_ptr=&line[0];
  253.                   while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  254.                     line_ptr++;
  255.                   if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  256.                     tilt=default_tilt;
  257.                   else
  258.                     {
  259.                       num_assigned=sscanf(line_ptr,"%lf",&tilt);
  260.                       if ((num_assigned == 0) || (num_assigned == EOF))
  261.                         tilt=(double) 0.0;
  262.                     }
  263.                 }
  264.               while ((tilt < (double) 30.0) || (tilt > (double) 60.0));
  265.               printf("\n     Random number seed (8 or fewer digits) [%s]?  ",
  266.                &default_seed[0]);
  267.               fflush(stdin);
  268.               fgets(&line[0],256,stdin);
  269.               line_ptr=&line[0];
  270.               while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  271.                 line_ptr++;
  272.               if ((*line_ptr != '\n') && (*line_ptr != '\0'))
  273.                 {
  274.                   seed_index=0;
  275.                   while ((seed_index < 8) 
  276.                   &&     (*line_ptr)
  277.                   &&     (*line_ptr != '\n'))
  278.                     default_seed[seed_index++]=*(line_ptr++);
  279.                   default_seed[seed_index]='\0';
  280.                 }
  281.               strcpy(&seed[0],&default_seed[0]);
  282.               default_num_columns=num_columns;
  283.               default_tilt=tilt;
  284.               max_x=8*(num_columns/2)+6;
  285.               max_x_plus_1=max_x+1;
  286.               max_y=4*num_rows;
  287.               max_y_plus_1=max_y+1;
  288.               num_rooms_in_maze=num_rows*num_columns-(num_columns/2);
  289.               if (memory_allocated(&computer_page,&user_page,max_x_plus_1,
  290.                max_y_plus_1,&stack,num_rooms_in_maze))
  291.                 {
  292.                   printf(
  293. "\n     While the maze is being generated, a spinning cursor is displayed:  ");
  294.                   generate_maze(&seed[0],computer_page,max_x,max_y,stack,
  295.                    num_rooms_in_maze,num_columns,num_rows);
  296.                   registerbgidriver(EGAVGA_driver);
  297.                   /*
  298.                      See the Borland documentation on the
  299.                      utilities "BINOBJ" and "TLIB" for 
  300.                      information on how to link "EGAVGA.BGI"
  301.                      into a program from "GRAPHICS.LIB".
  302.                   */
  303.                   GraphDriver=GRAPHICS_DRIVER;
  304.                   GraphMode=GRAPHICS_MODE;
  305.                   initgraph(&GraphDriver,&GraphMode,"");
  306.                   ErrorCode=graphresult();
  307.                   if (ErrorCode == 0)
  308.                     {
  309.                       getpalette(&palette);
  310.                       for (color_num=0; 
  311.                        color_num < (NUM_COLORS-3);
  312.                        color_num++)
  313.                         { /* evenly spaced shades of gray */
  314.                           tint=(63*color_num)/(NUM_COLORS-3);
  315.                           tint&=0xfc;
  316.                           setrgbpalette(
  317.                            palette.colors[color_num],
  318.                            tint,tint,tint);
  319.                         }
  320.                       setrgbpalette(
  321.                        palette.colors[BACKOUT_COLOR],
  322.                        0xfc,0xfc,0);
  323.                       setrgbpalette(
  324.                        palette.colors[ADVANCE_COLOR],
  325.                        0,0xfc,0);
  326.                       setrgbpalette(
  327.                        palette.colors[SOLUTION_COLOR],
  328.                        0xfc,0,0);
  329.                       settextjustify(CENTER_TEXT,BOTTOM_TEXT);
  330.                       settextstyle(DEFAULT_FONT,HORIZ_DIR,0);
  331.                       setcolor(NUM_COLORS-4);
  332.                       outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  333.                 "Home PgUp PgDn End \030 \031 - Move    S - Solve    Q - Quit");
  334.                       radians_per_degree=atan(1.0)/45.0;
  335.                       radians=tilt*radians_per_degree;
  336.                       sin_tilt=sin(radians);
  337.                       cos_tilt=cos(radians);
  338.                       x_max=3.0*(((double) num_columns)-1.0)/2.0+2.0
  339.                        +RELATIVE_WIDTH_OF_WALL/sqrt_3;
  340.                       pixels_per_x
  341.                        =(((double) WIDTH_OF_GRAPHICS_IN_PIXELS)-1.0)
  342.                        /(x_max*(x_max/(x_max-RELATIVE_HEIGHT_OF_WALL)));
  343.                       x_offset=(x_max/2.0)*(RELATIVE_HEIGHT_OF_WALL
  344.                        /(x_max-RELATIVE_HEIGHT_OF_WALL));
  345.                       y_max
  346.                        =((double) num_rows)*sqrt_3+RELATIVE_WIDTH_OF_WALL;
  347.                       pixels_per_z
  348.                        =(((double) HEIGHT_OF_GRAPHICS_IN_PIXELS)-1.0)/y_max;
  349.                       if (y_max > x_max)
  350.                         rel_dist_of_user_from_screen=y_max;
  351.                       else
  352.                         rel_dist_of_user_from_screen=x_max;
  353.                       output_maze(computer_page,max_x,max_y,x_max,x_offset,
  354.                        y_max,cos_tilt,sin_tilt,pixels_per_x,pixels_per_z,
  355.                        rel_dist_of_user_from_screen);
  356.                       let_user_try_to_solve(&response,max_x,max_y,computer_page,
  357.                        user_page,x_max,x_offset,y_max,cos_tilt,sin_tilt,
  358.                        pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
  359.                       if ((response == (int) 's')
  360.                       ||  (response == (int) 'S'))
  361.                         {
  362.                           display_solution(max_y,computer_page,x_max,x_offset,
  363.                            y_max,cos_tilt,sin_tilt,pixels_per_x,pixels_per_z,
  364.                            rel_dist_of_user_from_screen);
  365.                           setcolor(NUM_COLORS-4);
  366.                           outtextxy(NUM_X_PIXELS/2,
  367.                            NUM_Y_PIXELS-1,
  368.                            "Press a key to continue.");
  369.                           response=getch();
  370.                           if (response == 0)
  371.                             response=getch();
  372.                         }
  373.                       closegraph();
  374.                     }
  375.                   else
  376.                     {
  377.                       printf("     Fatal error:  %s\n",
  378.                        grapherrormsg(ErrorCode));
  379.                       fatal_error=TRUE;
  380.                     }
  381.                   free_memory(&computer_page,&user_page,max_y_plus_1,&stack);
  382.                 }
  383.               else
  384.                 {
  385.                   fatal_error=TRUE;
  386.                   printf("     Fatal error:  out of memory.\n");
  387.                 }
  388.             }
  389.         }
  390.       while ((! fatal_error) && (user_still_interested));
  391.       if (! fatal_error)
  392.         put_defaults(argv[0],default_num_columns,default_tilt,
  393.          &default_seed[0]);
  394.       return fatal_error;
  395.     }
  396.  
  397. static void get_defaults(
  398.   char   *argv,
  399.   int    *default_num_columns,
  400.   double *default_tilt,
  401.   char   *default_seed)
  402.     {
  403.       register int  arg_index;
  404.       static   char *arg_ptr;
  405.                FILE *defaults;
  406.       static   char file_name [256];
  407.       static   int  last_period_index;
  408.       static   char line [256];
  409.       static   char *line_ptr;
  410.       static   int  num_assigned;
  411.       static   int  seed_length;
  412.       static   char *seed_ptr;
  413.  
  414.       arg_index=0;
  415.       arg_ptr=argv;
  416.       last_period_index=-1;
  417.       while ((*arg_ptr) && (arg_index < 252))
  418.         {
  419.           if (*arg_ptr == '.')
  420.             last_period_index=arg_index;
  421.           file_name[arg_index++]=*(arg_ptr++);
  422.         }
  423.       if ((*arg_ptr) || (last_period_index < 0))
  424.         {
  425.           *default_num_columns=17;
  426.           *default_tilt=(double) 30.0;
  427.           default_seed[0]='1';
  428.           default_seed[1]='\0';
  429.         }
  430.       else
  431.         {
  432.           file_name[++last_period_index]='I';
  433.           file_name[++last_period_index]='N';
  434.           file_name[++last_period_index]='I';
  435.           file_name[++last_period_index]='\0';
  436.           if ((defaults=fopen(&file_name[0],"r")) == NULL)
  437.             {
  438.               *default_num_columns=17;
  439.               *default_tilt=(double) 30.0;
  440.               default_seed[0]='1';
  441.               default_seed[1]='\0';
  442.             }
  443.           else
  444.             {
  445.               fgets(&line[0],256,defaults);
  446.               line_ptr=&line[0];
  447.               while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  448.                 line_ptr++;
  449.               if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  450.                 *default_num_columns=17;
  451.               else
  452.                 {
  453.                   num_assigned=sscanf(line_ptr,"%d",default_num_columns);
  454.                   if ((num_assigned == 0) || (num_assigned == EOF))
  455.                     *default_num_columns=17;
  456.                 }
  457.               fgets(&line[0],256,defaults);
  458.               line_ptr=&line[0];
  459.               while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  460.                 line_ptr++;
  461.               if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  462.                 *default_tilt=(double) 30.0;
  463.               else
  464.                 {
  465.                   num_assigned=sscanf(line_ptr,"%lf",default_tilt);
  466.                   if ((num_assigned == 0) || (num_assigned == EOF))
  467.                     *default_tilt=(double) 30.0;
  468.                 }
  469.               fgets(&line[0],256,defaults);
  470.               line_ptr=&line[0];
  471.               while ((*line_ptr == ' ') || (*line_ptr == (char) 9))
  472.                 line_ptr++;
  473.               seed_ptr=default_seed;
  474.               if ((*line_ptr == '\n') || (*line_ptr == '\0'))
  475.                 *(seed_ptr++)='1';
  476.               else
  477.                 {
  478.                   seed_length=0;
  479.                   while ((seed_length < 8)
  480.                   &&     (*line_ptr)
  481.                   &&     (*line_ptr != '\n')) 
  482.                     {
  483.                       *(seed_ptr++)=*(line_ptr++);
  484.                       seed_length++;
  485.                     }
  486.                 }
  487.               *seed_ptr='\0';
  488.               fclose(defaults);
  489.             }
  490.         }
  491.       return;
  492.     }
  493.  
  494. void interrupt new_critical_error_handler()
  495.     {
  496.       file_opened=FALSE;
  497.       return;
  498.     }
  499.  
  500. static void put_defaults(
  501.   char   *argv,
  502.   int    num_columns,
  503.   double tilt,
  504.   char   *seed)
  505.     {
  506.       static int  arg_index;
  507.       static char *arg_ptr;
  508.              FILE *defaults;
  509.       static char file_name [256];
  510.       static int  last_period_index;
  511.  
  512.       arg_index=0;
  513.       arg_ptr=argv;
  514.       last_period_index=-1;
  515.       while ((*arg_ptr) && (arg_index < 252))
  516.         {
  517.           if (*arg_ptr == '.')
  518.             last_period_index=arg_index;
  519.           file_name[arg_index++]=*(arg_ptr++);
  520.         }
  521.       if ((*arg_ptr == '\0') && (last_period_index >= 0))
  522.         {
  523.           file_name[++last_period_index]='I';
  524.           file_name[++last_period_index]='N';
  525.           file_name[++last_period_index]='I';
  526.           file_name[++last_period_index]='\0';
  527.           old_critical_error_handler=getvect(0x24);
  528.           setvect(0x24,new_critical_error_handler);
  529.           file_opened=TRUE;
  530.           if ((defaults=fopen(&file_name[0],"w")) != NULL)
  531.             {
  532.               setvect(0x24,old_critical_error_handler);
  533.               if (file_opened)
  534.                 {
  535.                   fprintf(defaults,"%d\n%lf\n%s\n",num_columns,tilt,seed);
  536.                   fclose(defaults);
  537.                 }
  538.             }
  539.           else 
  540.             setvect(0x24,old_critical_error_handler);           
  541.         }
  542.       return;
  543.     }
  544.  
  545. static void get_corner(
  546.   double     x,
  547.   double     y,
  548.   double     z,
  549.   double     pixels_per_x,
  550.   double     pixels_per_z,
  551.   double     cos_tilt,
  552.   double     sin_tilt,
  553.   double     rel_dist_of_user_from_screen,
  554.   double     x_max,
  555.   double     x_offset,
  556.   double     y_max,
  557.   corner_rec *corner)
  558.     {
  559.       double x_adjusted;
  560.       double y_prime;
  561.       double z_adjusted;
  562.       double z_prime;
  563.       
  564.       y_prime=(y_max-y)*cos_tilt-z*sin_tilt;
  565.       z_prime=(y_max-y)*sin_tilt+z*cos_tilt;
  566.       z_adjusted=(y_max/2.0)+rel_dist_of_user_from_screen
  567.        *(z_prime-(y_max/2.0))/(y_prime+rel_dist_of_user_from_screen);
  568.       x_adjusted=(x_max/2.0)+rel_dist_of_user_from_screen
  569.        *(x-(x_max/2.0))/(y_prime+rel_dist_of_user_from_screen);
  570.       x_adjusted+=x_offset;
  571.       corner->x=(int) (pixels_per_x*x_adjusted);
  572.       corner->y
  573.        =(HEIGHT_OF_GRAPHICS_IN_PIXELS-1)-((int) (pixels_per_z*z_adjusted));
  574.       return;
  575.     }
  576.  
  577. static void display_quadrilateral(
  578.   double x_max,
  579.   double x_offset,
  580.   double y_max,
  581.   double x0,
  582.   double y0,
  583.   double z0,
  584.   double x1,
  585.   double y1,
  586.   double z1,
  587.   double x2,
  588.   double y2,
  589.   double z2,
  590.   double x3,
  591.   double y3,
  592.   double z3,
  593.   double pixels_per_x,
  594.   double pixels_per_z,
  595.   double cos_tilt,
  596.   double sin_tilt,
  597.   double rel_dist_of_user_from_screen,
  598.   int    color)
  599.     {
  600.       static corner_rec quadrilateral [4];
  601.  
  602.       get_corner(x0,y0,z0,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  603.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[0]);
  604.       get_corner(x1,y1,z1,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  605.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[1]);
  606.       get_corner(x2,y2,z2,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  607.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[2]);
  608.       get_corner(x3,y3,z3,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  609.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&quadrilateral[3]);
  610.       setcolor(color);
  611.       setfillstyle(SOLID_FILL,color);
  612.       fillpoly(4,&(quadrilateral[0].x));
  613.       return;
  614.     }
  615.  
  616. static void display_triangle(
  617.   double x_max,
  618.   double x_offset,
  619.   double y_max,
  620.   double x0,
  621.   double y0,
  622.   double z0,
  623.   double x1,
  624.   double y1,
  625.   double z1,
  626.   double x2,
  627.   double y2,
  628.   double z2,
  629.   double pixels_per_x,
  630.   double pixels_per_z,
  631.   double cos_tilt,
  632.   double sin_tilt,
  633.   double rel_dist_of_user_from_screen,
  634.   int    color)
  635.     {
  636.       static corner_rec triangle [3];
  637.  
  638.       get_corner(x0,y0,z0,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  639.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&triangle[0]);
  640.       get_corner(x1,y1,z1,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  641.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&triangle[1]);
  642.       get_corner(x2,y2,z2,pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  643.        rel_dist_of_user_from_screen,x_max,x_offset,y_max,&triangle[2]);
  644.       setcolor(color);
  645.       setfillstyle(SOLID_FILL,color);
  646.       fillpoly(3,&(triangle[0].x));
  647.       return;
  648.     }
  649.  
  650. static void output_triangle(
  651.   double       x_max,
  652.   double       x_offset,
  653.   double       y_max,
  654.   triangle_rec *triangle,
  655.   double       pixels_per_x,
  656.   double       pixels_per_z,
  657.   double       cos_tilt,
  658.   double       sin_tilt,
  659.   double       rel_dist_of_user_from_screen,
  660.   int          first_pass,
  661.   int          face_color)
  662.     {
  663.       if (first_pass)
  664.         {
  665.           if (((*triangle).vertex[1].x < x_max/2.0)
  666.           &&  ((*triangle).vertex[1].x > (*triangle).vertex[0].x))
  667.             display_quadrilateral(x_max,x_offset,y_max,
  668.              (*triangle).vertex[2].x,(*triangle).vertex[2].y,
  669.              RELATIVE_HEIGHT_OF_WALL,
  670.              (*triangle).vertex[1].x,(*triangle).vertex[1].y,
  671.              RELATIVE_HEIGHT_OF_WALL,
  672.              (*triangle).vertex[1].x,(*triangle).vertex[1].y,0.0,
  673.              (*triangle).vertex[2].x,(*triangle).vertex[2].y,0.0,
  674.              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  675.              rel_dist_of_user_from_screen,TRIANGLE_SSW_NNE_COLOR);
  676.           if (((*triangle).vertex[1].x > x_max/2.0)
  677.           &&  ((*triangle).vertex[1].x < (*triangle).vertex[2].x))
  678.             display_quadrilateral(x_max,x_offset,y_max,
  679.              (*triangle).vertex[1].x,(*triangle).vertex[1].y,
  680.              RELATIVE_HEIGHT_OF_WALL,
  681.              (*triangle).vertex[0].x,(*triangle).vertex[0].y,
  682.              RELATIVE_HEIGHT_OF_WALL,
  683.              (*triangle).vertex[0].x,(*triangle).vertex[0].y,0.0,
  684.              (*triangle).vertex[1].x,(*triangle).vertex[1].y,0.0,
  685.              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  686.              rel_dist_of_user_from_screen,TRIANGLE_SSE_NNW_COLOR);
  687.         }
  688.       else
  689.         {
  690.           display_quadrilateral(x_max,x_offset,y_max,
  691.            (*triangle).vertex[0].x,(*triangle).vertex[0].y,
  692.            RELATIVE_HEIGHT_OF_WALL,
  693.            (*triangle).vertex[2].x,(*triangle).vertex[2].y,
  694.            RELATIVE_HEIGHT_OF_WALL,
  695.            (*triangle).vertex[2].x,(*triangle).vertex[2].y,0.0,
  696.            (*triangle).vertex[0].x,(*triangle).vertex[0].y,0.0,
  697.            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  698.            rel_dist_of_user_from_screen,face_color);
  699.           display_triangle(x_max,x_offset,y_max,
  700.            (*triangle).vertex[0].x,(*triangle).vertex[0].y,
  701.            RELATIVE_HEIGHT_OF_WALL,
  702.            (*triangle).vertex[1].x,(*triangle).vertex[1].y,
  703.            RELATIVE_HEIGHT_OF_WALL,
  704.            (*triangle).vertex[2].x,(*triangle).vertex[2].y,
  705.            RELATIVE_HEIGHT_OF_WALL,
  706.            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  707.            rel_dist_of_user_from_screen,TOP_COLOR);
  708.         }
  709.       return;
  710.     }
  711.  
  712. static void output_rectangle(
  713.   double        x_max,
  714.   double        x_offset,
  715.   double        y_max,
  716.   rectangle_rec *rectangle,
  717.   double        pixels_per_x,
  718.   double        pixels_per_z,
  719.   double        cos_tilt,
  720.   double        sin_tilt,
  721.   double        rel_dist_of_user_from_screen,
  722.   int           face_color)
  723.     {
  724.       display_quadrilateral(x_max,x_offset,y_max,
  725.        (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,
  726.        RELATIVE_HEIGHT_OF_WALL,
  727.        (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,
  728.        RELATIVE_HEIGHT_OF_WALL,
  729.        (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,0.0,
  730.        (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,0.0,
  731.        pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  732.        rel_dist_of_user_from_screen,face_color);
  733.       display_quadrilateral(x_max,x_offset,y_max,
  734.        (*rectangle).vertex[0].x,(*rectangle).vertex[0].y,
  735.        RELATIVE_HEIGHT_OF_WALL,
  736.        (*rectangle).vertex[1].x,(*rectangle).vertex[1].y,
  737.        RELATIVE_HEIGHT_OF_WALL,
  738.        (*rectangle).vertex[2].x,(*rectangle).vertex[2].y,
  739.        RELATIVE_HEIGHT_OF_WALL,
  740.        (*rectangle).vertex[3].x,(*rectangle).vertex[3].y,
  741.        RELATIVE_HEIGHT_OF_WALL,
  742.        pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  743.        rel_dist_of_user_from_screen,TOP_COLOR);
  744.       return;
  745.     }
  746.  
  747. static void output_maze(
  748.   char   **page,
  749.   int    max_x,
  750.   int    max_y,
  751.   double x_max,
  752.   double x_offset,
  753.   double y_max,
  754.   double cos_tilt,
  755.   double sin_tilt,
  756.   double pixels_per_x,
  757.   double pixels_per_z,
  758.   double rel_dist_of_user_from_screen)
  759.     {
  760.       static   rectangle_rec base_rectangle [6];
  761.       static   triangle_rec  base_triangle [4];
  762.       static   int           object_num;
  763.       static   rectangle_rec rectangle [6];
  764.       static   triangle_rec  triangle [4];
  765.       static   int           vertex_num;
  766.       register int           x;
  767.       static   int           x_mod_8;
  768.       register int           y;
  769.       static   int           y_mod_4;
  770.       static   double        y_offset;
  771.  
  772.       base_triangle[0].vertex[0].x=0.0;
  773.       base_triangle[0].vertex[0].y=RELATIVE_WIDTH_OF_WALL+sqrt_3/2.0;
  774.       base_triangle[0].vertex[1].x=0.0;
  775.       base_triangle[0].vertex[1].y=sqrt_3/2.0;
  776.       base_triangle[0].vertex[2].x=RELATIVE_WIDTH_OF_WALL*sqrt_3/2.0;
  777.       base_triangle[0].vertex[2].y=(RELATIVE_WIDTH_OF_WALL+sqrt_3)/2.0;
  778.       base_triangle[1].vertex[0].x=(1.0-RELATIVE_WIDTH_OF_WALL/sqrt_3)/2.0;
  779.       base_triangle[1].vertex[0].y=RELATIVE_WIDTH_OF_WALL/2.0;
  780.       base_triangle[1].vertex[1].x=0.5+RELATIVE_WIDTH_OF_WALL/sqrt_3;
  781.       base_triangle[1].vertex[1].y=0.0;
  782.       base_triangle[1].vertex[2].x=base_triangle[1].vertex[1].x;
  783.       base_triangle[1].vertex[2].y=RELATIVE_WIDTH_OF_WALL;
  784.       base_triangle[2].vertex[0].x=1.5;
  785.       base_triangle[2].vertex[0].y=RELATIVE_WIDTH_OF_WALL;
  786.       base_triangle[2].vertex[1].x=1.5;
  787.       base_triangle[2].vertex[1].y=0.0;
  788.       base_triangle[2].vertex[2].x=1.5*(1.0+RELATIVE_WIDTH_OF_WALL/sqrt_3);
  789.       base_triangle[2].vertex[2].y=RELATIVE_WIDTH_OF_WALL/2.0;
  790.       base_triangle[3].vertex[0].x=2.0-RELATIVE_WIDTH_OF_WALL/(2.0*sqrt_3);
  791.       base_triangle[3].vertex[0].y=base_triangle[0].vertex[2].y;
  792.       base_triangle[3].vertex[1].x=2.0+RELATIVE_WIDTH_OF_WALL/sqrt_3;
  793.       base_triangle[3].vertex[1].y=base_triangle[0].vertex[1].y;
  794.       base_triangle[3].vertex[2].x=base_triangle[3].vertex[1].x;
  795.       base_triangle[3].vertex[2].y=base_triangle[0].vertex[0].y;
  796.       base_rectangle[0].vertex[0].x=base_triangle[0].vertex[2].x;
  797.       base_rectangle[0].vertex[0].y=base_triangle[0].vertex[2].y;
  798.       base_rectangle[0].vertex[1].x=base_triangle[1].vertex[1].x;
  799.       base_rectangle[0].vertex[1].y=sqrt_3;
  800.       base_rectangle[0].vertex[2].x=base_triangle[1].vertex[0].x;
  801.       base_rectangle[0].vertex[2].y=sqrt_3+RELATIVE_WIDTH_OF_WALL/2.0;
  802.       base_rectangle[0].vertex[3].x=base_triangle[0].vertex[0].x;
  803.       base_rectangle[0].vertex[3].y=base_triangle[0].vertex[0].y;
  804.       base_rectangle[1].vertex[0].x=base_triangle[0].vertex[1].x;
  805.       base_rectangle[1].vertex[0].y=base_triangle[0].vertex[1].y;
  806.       base_rectangle[1].vertex[1].x=base_triangle[1].vertex[0].x;
  807.       base_rectangle[1].vertex[1].y=base_triangle[1].vertex[0].y;
  808.       base_rectangle[1].vertex[2].x=base_triangle[1].vertex[2].x;
  809.       base_rectangle[1].vertex[2].y=base_triangle[1].vertex[2].y;
  810.       base_rectangle[1].vertex[3].x=base_triangle[0].vertex[2].x;
  811.       base_rectangle[1].vertex[3].y=base_triangle[0].vertex[2].y;         
  812.       base_rectangle[2].vertex[0].x=base_triangle[1].vertex[1].x;
  813.       base_rectangle[2].vertex[0].y=base_triangle[1].vertex[1].y;
  814.       base_rectangle[2].vertex[1].x=base_triangle[2].vertex[1].x;
  815.       base_rectangle[2].vertex[1].y=base_triangle[2].vertex[1].y;
  816.       base_rectangle[2].vertex[2].x=base_triangle[2].vertex[0].x;
  817.       base_rectangle[2].vertex[2].y=base_triangle[2].vertex[0].y;
  818.       base_rectangle[2].vertex[3].x=base_triangle[1].vertex[2].x;
  819.       base_rectangle[2].vertex[3].y=base_triangle[1].vertex[2].y;         
  820.       base_rectangle[3].vertex[0].x=base_triangle[2].vertex[2].x;
  821.       base_rectangle[3].vertex[0].y=base_triangle[2].vertex[2].y;
  822.       base_rectangle[3].vertex[1].x=base_triangle[3].vertex[1].x;
  823.       base_rectangle[3].vertex[1].y=base_triangle[3].vertex[1].y;
  824.       base_rectangle[3].vertex[2].x=base_triangle[3].vertex[0].x;
  825.       base_rectangle[3].vertex[2].y=base_triangle[3].vertex[0].y;
  826.       base_rectangle[3].vertex[3].x=base_triangle[2].vertex[0].x;
  827.       base_rectangle[3].vertex[3].y=base_triangle[2].vertex[0].y;         
  828.       base_rectangle[4].vertex[0].x=base_triangle[3].vertex[1].x;
  829.       base_rectangle[4].vertex[0].y=base_triangle[3].vertex[1].y;
  830.       base_rectangle[4].vertex[1].x=base_triangle[3].vertex[1].x
  831.        +(base_triangle[2].vertex[1].x-base_triangle[1].vertex[1].x);
  832.       base_rectangle[4].vertex[1].y=base_triangle[3].vertex[1].y;
  833.       base_rectangle[4].vertex[2].x=base_rectangle[4].vertex[1].x;
  834.       base_rectangle[4].vertex[2].y=base_triangle[3].vertex[2].y;
  835.       base_rectangle[4].vertex[3].x=base_triangle[3].vertex[2].x;
  836.       base_rectangle[4].vertex[3].y=base_triangle[3].vertex[2].y;         
  837.       base_rectangle[5].vertex[0].x=base_rectangle[0].vertex[1].x
  838.        +(base_triangle[2].vertex[1].x-base_triangle[1].vertex[1].x);
  839.       base_rectangle[5].vertex[0].y=base_rectangle[0].vertex[1].y;
  840.       base_rectangle[5].vertex[1].x=base_triangle[3].vertex[0].x;
  841.       base_rectangle[5].vertex[1].y=base_triangle[3].vertex[0].y;
  842.       base_rectangle[5].vertex[2].x=base_triangle[3].vertex[2].x;
  843.       base_rectangle[5].vertex[2].y=base_triangle[3].vertex[2].y;
  844.       base_rectangle[5].vertex[3].x=base_rectangle[0].vertex[2].x
  845.        +(base_triangle[2].vertex[2].x-base_triangle[1].vertex[0].x);
  846.       base_rectangle[5].vertex[3].y=base_rectangle[0].vertex[2].y;
  847.       rectangle[0].vertex[0].x=base_triangle[1].vertex[1].x;
  848.       rectangle[0].vertex[0].y=base_triangle[1].vertex[1].y;
  849.       rectangle[0].vertex[1].x=x_max-base_triangle[1].vertex[1].x;
  850.       rectangle[0].vertex[1].y=base_triangle[1].vertex[1].y;
  851.       rectangle[0].vertex[2].x=x_max-base_triangle[1].vertex[2].x;
  852.       rectangle[0].vertex[2].y=base_triangle[1].vertex[2].y;
  853.       rectangle[0].vertex[3].x=base_triangle[1].vertex[2].x;
  854.       rectangle[0].vertex[3].y=base_triangle[1].vertex[2].y;
  855.       rectangle[1].vertex[0].x=base_triangle[0].vertex[1].x;
  856.       rectangle[1].vertex[0].y=base_triangle[0].vertex[1].y;
  857.       rectangle[1].vertex[1].x=x_max-base_triangle[0].vertex[1].x;
  858.       rectangle[1].vertex[1].y=base_triangle[0].vertex[1].y;
  859.       rectangle[1].vertex[2].x=x_max-base_triangle[1].vertex[2].x;
  860.       rectangle[1].vertex[2].y=base_triangle[1].vertex[2].y;
  861.       rectangle[1].vertex[3].x=base_triangle[1].vertex[2].x;
  862.       rectangle[1].vertex[3].y=base_triangle[1].vertex[2].y;
  863.       rectangle[2].vertex[0].x=base_triangle[0].vertex[1].x;
  864.       rectangle[2].vertex[0].y=base_triangle[0].vertex[1].y;
  865.       rectangle[2].vertex[1].x=x_max-base_triangle[0].vertex[1].x;
  866.       rectangle[2].vertex[1].y=base_triangle[0].vertex[1].y;
  867.       rectangle[2].vertex[2].x=x_max-base_triangle[0].vertex[0].x;
  868.       rectangle[2].vertex[2].y=base_triangle[0].vertex[0].y;
  869.       rectangle[2].vertex[3].x=base_triangle[0].vertex[0].x;
  870.       rectangle[2].vertex[3].y=base_triangle[0].vertex[0].y;
  871.       rectangle[3].vertex[0].x=base_triangle[0].vertex[0].x;
  872.       rectangle[3].vertex[0].y=base_triangle[0].vertex[0].y;
  873.       rectangle[3].vertex[1].x=x_max-base_triangle[0].vertex[0].x;
  874.       rectangle[3].vertex[1].y=base_triangle[0].vertex[0].y;
  875.       rectangle[3].vertex[2].x=x_max-base_rectangle[0].vertex[1].x;
  876.       rectangle[3].vertex[2].y=base_rectangle[0].vertex[1].y;
  877.       rectangle[3].vertex[3].x=base_rectangle[0].vertex[1].x;
  878.       rectangle[3].vertex[3].y=base_rectangle[0].vertex[1].y;
  879.       for (y=0; y <= max_y-1; y+=4)
  880.         {
  881.           if (y > 0) 
  882.             {
  883.               display_quadrilateral(x_max,x_offset,y_max,
  884.                rectangle[0].vertex[0].x,rectangle[0].vertex[0].y,0.0,
  885.                rectangle[0].vertex[1].x,rectangle[0].vertex[1].y,0.0,
  886.                rectangle[0].vertex[2].x,rectangle[0].vertex[2].y,0.0,
  887.                rectangle[0].vertex[3].x,rectangle[0].vertex[3].y,0.0,
  888.                pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  889.                rel_dist_of_user_from_screen,FLOOR_COLOR);
  890.               display_quadrilateral(x_max,x_offset,y_max,
  891.                rectangle[1].vertex[0].x,rectangle[1].vertex[0].y,0.0,
  892.                rectangle[1].vertex[1].x,rectangle[1].vertex[1].y,0.0,
  893.                rectangle[1].vertex[2].x,rectangle[1].vertex[2].y,0.0,
  894.                rectangle[1].vertex[3].x,rectangle[1].vertex[3].y,0.0,
  895.                pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  896.                rel_dist_of_user_from_screen,FLOOR_COLOR);
  897.             }
  898.           display_quadrilateral(x_max,x_offset,y_max,
  899.            rectangle[2].vertex[0].x,rectangle[2].vertex[0].y,0.0,
  900.            rectangle[2].vertex[1].x,rectangle[2].vertex[1].y,0.0,
  901.            rectangle[2].vertex[2].x,rectangle[2].vertex[2].y,0.0,
  902.            rectangle[2].vertex[3].x,rectangle[2].vertex[3].y,0.0,
  903.            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  904.            rel_dist_of_user_from_screen,FLOOR_COLOR);
  905.           if (y < max_y-4)
  906.             {
  907.               display_quadrilateral(x_max,x_offset,y_max,
  908.                rectangle[3].vertex[0].x,rectangle[3].vertex[0].y,0.0,
  909.                rectangle[3].vertex[1].x,rectangle[3].vertex[1].y,0.0,
  910.                rectangle[3].vertex[2].x,rectangle[3].vertex[2].y,0.0,
  911.                rectangle[3].vertex[3].x,rectangle[3].vertex[3].y,0.0,
  912.                pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  913.                rel_dist_of_user_from_screen,FLOOR_COLOR);
  914.             }
  915.           for (object_num=0; object_num < 4; object_num++)
  916.             for (vertex_num=0; vertex_num < 4; vertex_num++)
  917.               (rectangle[object_num].vertex[vertex_num].y)+=sqrt_3;
  918.         }
  919.       rectangle[0].vertex[0].x=base_triangle[1].vertex[0].x;
  920.       rectangle[0].vertex[0].y=base_triangle[1].vertex[0].y;
  921.       rectangle[0].vertex[1].x=base_triangle[1].vertex[1].x;
  922.       rectangle[0].vertex[1].y=base_triangle[1].vertex[1].y;
  923.       rectangle[0].vertex[2].x=base_triangle[2].vertex[1].x;
  924.       rectangle[0].vertex[2].y=base_triangle[2].vertex[1].y;
  925.       rectangle[0].vertex[3].x=base_triangle[2].vertex[2].x;
  926.       rectangle[0].vertex[3].y=base_triangle[2].vertex[2].y;
  927.       rectangle[1].vertex[0].x=base_triangle[0].vertex[1].x;
  928.       rectangle[1].vertex[0].y=base_triangle[0].vertex[1].y;
  929.       rectangle[1].vertex[1].x=base_triangle[1].vertex[0].x;
  930.       rectangle[1].vertex[1].y=base_triangle[1].vertex[0].y;
  931.       rectangle[1].vertex[2].x=base_triangle[2].vertex[2].x;
  932.       rectangle[1].vertex[2].y=base_triangle[2].vertex[2].y;
  933.       rectangle[1].vertex[3].x=base_triangle[3].vertex[1].x;
  934.       rectangle[1].vertex[3].y=base_triangle[3].vertex[1].y;
  935.       rectangle[2].vertex[0].x=base_triangle[0].vertex[0].x;
  936.       rectangle[2].vertex[0].y=base_triangle[0].vertex[0].y;
  937.       rectangle[2].vertex[1].x=base_triangle[0].vertex[1].x;
  938.       rectangle[2].vertex[1].y=base_triangle[0].vertex[1].y;
  939.       rectangle[2].vertex[2].x=base_triangle[3].vertex[1].x;
  940.       rectangle[2].vertex[2].y=base_triangle[3].vertex[1].y;
  941.       rectangle[2].vertex[3].x=base_triangle[3].vertex[2].x;
  942.       rectangle[2].vertex[3].y=base_triangle[3].vertex[2].y;
  943.       for (x=0; x <= max_x; x+=8)
  944.         {
  945.           for (object_num=0; object_num < 3; object_num++)
  946.             {
  947.               display_quadrilateral(x_max,x_offset,y_max,
  948.                rectangle[object_num].vertex[0].x,
  949.                rectangle[object_num].vertex[0].y,0.0,
  950.                rectangle[object_num].vertex[1].x,
  951.                rectangle[object_num].vertex[1].y,0.0,
  952.                rectangle[object_num].vertex[2].x,
  953.                rectangle[object_num].vertex[2].y,0.0,
  954.                rectangle[object_num].vertex[3].x,
  955.                rectangle[object_num].vertex[3].y,0.0,
  956.                pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  957.                rel_dist_of_user_from_screen,FLOOR_COLOR);
  958.               display_quadrilateral(x_max,x_offset,y_max,
  959.                rectangle[object_num].vertex[0].x,
  960.                y_max-rectangle[object_num].vertex[0].y,0.0,
  961.                rectangle[object_num].vertex[1].x,
  962.                y_max-rectangle[object_num].vertex[1].y,0.0,
  963.                rectangle[object_num].vertex[2].x,
  964.                y_max-rectangle[object_num].vertex[2].y,0.0,
  965.                rectangle[object_num].vertex[3].x,
  966.                y_max-rectangle[object_num].vertex[3].y,0.0,
  967.                pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  968.                rel_dist_of_user_from_screen,FLOOR_COLOR);
  969.               for (vertex_num=0; vertex_num < 4; vertex_num++)
  970.                 (rectangle[object_num].vertex[vertex_num].x)+=3.0;
  971.             }
  972.         }
  973.       y_mod_4=0;
  974.       y_offset=0.0;
  975.       for (y=0; y <= max_y; y++)
  976.         {
  977.           switch (y_mod_4)
  978.             {
  979.               case 0:
  980.                 x_mod_8=0;
  981.                 for (object_num=1; object_num <= 2; object_num++)
  982.                   for (vertex_num=0; vertex_num < 3; vertex_num++)
  983.                     {
  984.                       triangle[object_num].vertex[vertex_num].x
  985.                        =base_triangle[object_num].vertex[vertex_num].x;
  986.                       triangle[object_num].vertex[vertex_num].y
  987.                        =base_triangle[object_num].vertex[vertex_num].y
  988.                        +y_offset;
  989.                     }
  990.                 for (vertex_num=0; vertex_num < 4; vertex_num++)
  991.                   {
  992.                     rectangle[2].vertex[vertex_num].x
  993.                      =base_rectangle[2].vertex[vertex_num].x;
  994.                     rectangle[2].vertex[vertex_num].y
  995.                      =base_rectangle[2].vertex[vertex_num].y+y_offset;
  996.                   }
  997.                 for (x=0; x <= max_x; x++)
  998.                   {
  999.                     switch (x_mod_8)
  1000.                       {
  1001.                         case 2:
  1002.                           output_triangle(x_max,x_offset,y_max,&triangle[1],
  1003.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1004.                            rel_dist_of_user_from_screen,TRUE,
  1005.                            TRIANGLE_SSW_NNE_COLOR);
  1006.                           break;
  1007.                         case 4:
  1008.                           output_triangle(x_max,x_offset,y_max,&triangle[2],
  1009.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1010.                            rel_dist_of_user_from_screen,TRUE,
  1011.                            TRIANGLE_SSE_NNW_COLOR);
  1012.                           break;
  1013.                         default:
  1014.                           break;
  1015.                       }
  1016.                     if (++x_mod_8 >= 8)
  1017.                       {
  1018.                         x_mod_8=0;
  1019.                         for (object_num=1; object_num <= 2; object_num++)
  1020.                           for (vertex_num=0; vertex_num < 3; vertex_num++)
  1021.                             (triangle[object_num].vertex[vertex_num].x)+=3.0;
  1022.                         for (vertex_num=0; vertex_num < 4; vertex_num++)
  1023.                           (rectangle[2].vertex[vertex_num].x)+=3.0;
  1024.                       }
  1025.                   }
  1026.                 x_mod_8=0;
  1027.                 for (object_num=1; object_num <= 2; object_num++)
  1028.                   for (vertex_num=0; vertex_num < 3; vertex_num++)
  1029.                     {
  1030.                       triangle[object_num].vertex[vertex_num].x
  1031.                        =base_triangle[object_num].vertex[vertex_num].x;
  1032.                       triangle[object_num].vertex[vertex_num].y
  1033.                        =base_triangle[object_num].vertex[vertex_num].y
  1034.                        +y_offset;
  1035.                     }
  1036.                 for (vertex_num=0; vertex_num < 4; vertex_num++)
  1037.                   {
  1038.                     rectangle[2].vertex[vertex_num].x
  1039.                      =base_rectangle[2].vertex[vertex_num].x;
  1040.                     rectangle[2].vertex[vertex_num].y
  1041.                      =base_rectangle[2].vertex[vertex_num].y+y_offset;
  1042.                   }
  1043.                 for (x=0; x <= max_x; x++)
  1044.                   {
  1045.                     switch (x_mod_8)
  1046.                       {
  1047.                         case 2:
  1048.                           output_triangle(x_max,x_offset,y_max,&triangle[1],
  1049.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1050.                            rel_dist_of_user_from_screen,FALSE,
  1051.                            TRIANGLE_SE_NW_COLOR);
  1052.                           break;
  1053.                         case 3:
  1054.                           if (page[y][x] == 'W')
  1055.                             output_rectangle(x_max,x_offset,y_max,&rectangle[2],
  1056.                              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1057.                              rel_dist_of_user_from_screen,
  1058.                              RECTANGLE_W_E_COLOR);
  1059.                           break;
  1060.                         case 4:
  1061.                           output_triangle(x_max,x_offset,y_max,&triangle[2],
  1062.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1063.                            rel_dist_of_user_from_screen,FALSE,
  1064.                            TRIANGLE_SW_NE_COLOR);
  1065.                           break;
  1066.                         default:
  1067.                           break;
  1068.                       }
  1069.                     if (++x_mod_8 >= 8)
  1070.                       {
  1071.                         x_mod_8=0;
  1072.                         for (object_num=1; object_num <= 2; object_num++)
  1073.                           for (vertex_num=0; vertex_num < 3; vertex_num++)
  1074.                             (triangle[object_num].vertex[vertex_num].x)+=3.0;
  1075.                         for (vertex_num=0; vertex_num < 4; vertex_num++)
  1076.                           (rectangle[2].vertex[vertex_num].x)+=3.0;
  1077.                       }
  1078.                   }
  1079.                 break;
  1080.               case 1:
  1081.                 x_mod_8=0;
  1082.                 for (object_num=1; object_num <= 3; object_num+=2)
  1083.                   for (vertex_num=0; vertex_num < 4; vertex_num++)
  1084.                     {
  1085.                       rectangle[object_num].vertex[vertex_num].x
  1086.                        =base_rectangle[object_num].vertex[vertex_num].x;
  1087.                       rectangle[object_num].vertex[vertex_num].y
  1088.                        =base_rectangle[object_num].vertex[vertex_num].y
  1089.                        +y_offset;
  1090.                     }
  1091.                 for (x=0; x <= max_x; x++)
  1092.                   {
  1093.                     switch (x_mod_8)
  1094.                       {
  1095.                         case 1:
  1096.                           if (page[y][x] == 'W')
  1097.                             output_rectangle(x_max,x_offset,y_max,&rectangle[1],
  1098.                              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1099.                              rel_dist_of_user_from_screen,
  1100.                              RECTANGLE_SW_NE_COLOR);
  1101.                           break;
  1102.                         case 5:
  1103.                           if (page[y][x] == 'W')
  1104.                             output_rectangle(x_max,x_offset,y_max,&rectangle[3],
  1105.                              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1106.                              rel_dist_of_user_from_screen,
  1107.                              RECTANGLE_SE_NW_COLOR);
  1108.                           break;
  1109.                         default:
  1110.                           break;
  1111.                       }
  1112.                     if (++x_mod_8 >= 8)
  1113.                       {
  1114.                         x_mod_8=0;
  1115.                         for (object_num=1; object_num <= 3; object_num+=2)
  1116.                           for (vertex_num=0; vertex_num < 4; vertex_num++)
  1117.                             (rectangle[object_num].vertex[vertex_num].x)+=3.0;
  1118.                       }
  1119.                   }
  1120.                 break;
  1121.               case 2:
  1122.                 x_mod_8=0;
  1123.                 for (object_num=0; object_num <= 3; object_num+=3)
  1124.                   for (vertex_num=0; vertex_num < 3; vertex_num++)
  1125.                     {
  1126.                       triangle[object_num].vertex[vertex_num].x
  1127.                        =base_triangle[object_num].vertex[vertex_num].x;
  1128.                       triangle[object_num].vertex[vertex_num].y
  1129.                        =base_triangle[object_num].vertex[vertex_num].y
  1130.                        +y_offset;
  1131.                     }
  1132.                 for (vertex_num=0; vertex_num < 4; vertex_num++)
  1133.                   {
  1134.                     rectangle[4].vertex[vertex_num].x
  1135.                      =base_rectangle[4].vertex[vertex_num].x;
  1136.                     rectangle[4].vertex[vertex_num].y
  1137.                      =base_rectangle[4].vertex[vertex_num].y+y_offset;
  1138.                   }
  1139.                 for (x=0; x <= max_x; x++)
  1140.                   {
  1141.                     switch (x_mod_8)
  1142.                       {
  1143.                         case 0:
  1144.                           output_triangle(x_max,x_offset,y_max,&triangle[0],
  1145.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1146.                            rel_dist_of_user_from_screen,TRUE,
  1147.                            TRIANGLE_SSW_NNE_COLOR);
  1148.                           break;
  1149.                         case 6:
  1150.                           output_triangle(x_max,x_offset,y_max,&triangle[3],
  1151.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1152.                            rel_dist_of_user_from_screen,TRUE,
  1153.                            TRIANGLE_SSE_NNW_COLOR);
  1154.                           break;
  1155.                         default:
  1156.                           break;
  1157.                       }
  1158.                     if (++x_mod_8 >= 8)
  1159.                       {
  1160.                         x_mod_8=0;
  1161.                         for (object_num=0; object_num <= 3; object_num+=3)
  1162.                           for (vertex_num=0; vertex_num < 3; vertex_num++)
  1163.                             (triangle[object_num].vertex[vertex_num].x)+=3.0;
  1164.                         for (vertex_num=0; vertex_num < 4; vertex_num++)
  1165.                           (rectangle[4].vertex[vertex_num].x)+=3.0;
  1166.                       }
  1167.                   }
  1168.                 x_mod_8=0;
  1169.                 for (object_num=0; object_num <= 3; object_num+=3)
  1170.                   for (vertex_num=0; vertex_num < 3; vertex_num++)
  1171.                     {
  1172.                       triangle[object_num].vertex[vertex_num].x
  1173.                        =base_triangle[object_num].vertex[vertex_num].x;
  1174.                       triangle[object_num].vertex[vertex_num].y
  1175.                        =base_triangle[object_num].vertex[vertex_num].y
  1176.                        +y_offset;
  1177.                     }
  1178.                 for (vertex_num=0; vertex_num < 4; vertex_num++)
  1179.                   {
  1180.                     rectangle[4].vertex[vertex_num].x
  1181.                      =base_rectangle[4].vertex[vertex_num].x;
  1182.                     rectangle[4].vertex[vertex_num].y
  1183.                      =base_rectangle[4].vertex[vertex_num].y+y_offset;
  1184.                   }
  1185.                 for (x=0; x <= max_x; x++)
  1186.                   {
  1187.                     switch (x_mod_8)
  1188.                       {
  1189.                         case 0:
  1190.                           output_triangle(x_max,x_offset,y_max,&triangle[0],
  1191.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1192.                            rel_dist_of_user_from_screen,FALSE,
  1193.                            TRIANGLE_SW_NE_COLOR);
  1194.                           break;
  1195.                         case 6:
  1196.                           output_triangle(x_max,x_offset,y_max,&triangle[3],
  1197.                            pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1198.                            rel_dist_of_user_from_screen,FALSE,
  1199.                            TRIANGLE_SE_NW_COLOR);
  1200.                           break;
  1201.                         case 7:
  1202.                           if (page[y][x] == 'W')
  1203.                             output_rectangle(x_max,x_offset,y_max,&rectangle[4],
  1204.                              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1205.                              rel_dist_of_user_from_screen,
  1206.                              RECTANGLE_W_E_COLOR);
  1207.                           break;
  1208.                         default:
  1209.                           break;
  1210.                       }
  1211.                     if (++x_mod_8 >= 8)
  1212.                       {
  1213.                         x_mod_8=0;
  1214.                         for (object_num=0; object_num <= 3; object_num+=3)
  1215.                           for (vertex_num=0; vertex_num < 3; vertex_num++)
  1216.                             (triangle[object_num].vertex[vertex_num].x)+=3.0;
  1217.                         for (vertex_num=0; vertex_num < 4; vertex_num++)
  1218.                           (rectangle[4].vertex[vertex_num].x)+=3.0;
  1219.                       }
  1220.                   }
  1221.                 break;
  1222.               default:
  1223.                 x_mod_8=0;
  1224.                 for (object_num=0; object_num <= 5; object_num+=5)
  1225.                   for (vertex_num=0; vertex_num < 4; vertex_num++)
  1226.                     {
  1227.                       rectangle[object_num].vertex[vertex_num].x
  1228.                        =base_rectangle[object_num].vertex[vertex_num].x;
  1229.                       rectangle[object_num].vertex[vertex_num].y
  1230.                        =base_rectangle[object_num].vertex[vertex_num].y
  1231.                        +y_offset;
  1232.                     }
  1233.                 for (x=0; x <= max_x; x++)
  1234.                   {
  1235.                     switch (x_mod_8)
  1236.                       {
  1237.                         case 1:
  1238.                           if (page[y][x] == 'W')
  1239.                             output_rectangle(x_max,x_offset,y_max,&rectangle[0],
  1240.                              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1241.                              rel_dist_of_user_from_screen,
  1242.                              RECTANGLE_SE_NW_COLOR);
  1243.                           break;
  1244.                         case 5:
  1245.                           if (page[y][x] == 'W')
  1246.                             output_rectangle(x_max,x_offset,y_max,&rectangle[5],
  1247.                              pixels_per_x,pixels_per_z,cos_tilt,sin_tilt,
  1248.                              rel_dist_of_user_from_screen,
  1249.                              RECTANGLE_SW_NE_COLOR);
  1250.                           break;
  1251.                         default:
  1252.                           break;
  1253.                       }
  1254.                     if (++x_mod_8 >= 8)
  1255.                       {
  1256.                         x_mod_8=0;
  1257.                         for (object_num=0; object_num <= 5; object_num+=5)
  1258.                           for (vertex_num=0; vertex_num < 4; vertex_num++)
  1259.                             (rectangle[object_num].vertex[vertex_num].x)+=3.0;
  1260.                       }
  1261.                   }
  1262.                 break;
  1263.             }
  1264.           if (++y_mod_4 >= 4)
  1265.             {
  1266.               y_mod_4=0;
  1267.               y_offset+=sqrt_3;
  1268.             }
  1269.         }
  1270.       return;
  1271.     }
  1272.  
  1273. static int memory_allocated(
  1274.   char      ***computer_page,
  1275.   char      ***user_page,
  1276.   int       max_x_plus_1,
  1277.   int       max_y_plus_1,
  1278.   stack_rec **stack,
  1279.   int       num_rooms_in_maze)
  1280.     {
  1281.       static   int result;
  1282.       register int y;
  1283.  
  1284.       if (((*computer_page)
  1285.        =(char **) malloc(((size_t) max_y_plus_1)*sizeof(char *))) == NULL)
  1286.         result=FALSE;
  1287.       else
  1288.         {
  1289.           result=TRUE;
  1290.           for (y=0; ((result) && (y < max_y_plus_1)); y++)
  1291.            result=(((*computer_page)[y]
  1292.             =malloc(((size_t) max_x_plus_1)*sizeof(char))) != NULL);
  1293.           if (! result)
  1294.             {
  1295.               --y;
  1296.               while (y > 0)
  1297.                 free((void *) (*computer_page)[--y]);
  1298.               free((void *) *computer_page);
  1299.             }
  1300.         }
  1301.       if (result)
  1302.         {
  1303.           if (((*user_page)
  1304.            =(char **) malloc(((size_t) max_y_plus_1)*sizeof(char *))) == NULL)
  1305.             {
  1306.               result=FALSE;
  1307.               for (y=0; y < max_y_plus_1; y++)
  1308.                free((void *) (*computer_page)[y]);
  1309.               free((void *) *computer_page);
  1310.             }
  1311.           else
  1312.             {
  1313.               result=TRUE;
  1314.               for (y=0; ((result) && (y < max_y_plus_1)); y++)
  1315.                result=(((*user_page)[y]
  1316.                 =malloc(((size_t) max_x_plus_1)*sizeof(char))) != NULL);
  1317.               if (! result)
  1318.                 {
  1319.                   --y;
  1320.                   while (y > 0)
  1321.                     free((void *) (*user_page)[--y]);
  1322.                   free((void *) *user_page);
  1323.                   for (y=0; y < max_y_plus_1; y++)
  1324.                    free((void *) (*computer_page)[y]);
  1325.                   free((void *) *computer_page);
  1326.                 }
  1327.             }
  1328.         }
  1329.       if (result)
  1330.         {
  1331.           if ((*stack=(stack_rec *) malloc(
  1332.            ((unsigned int) num_rooms_in_maze)*sizeof(stack_rec))) == NULL)
  1333.             {
  1334.               result=FALSE;
  1335.               for (y=0; y < max_y_plus_1; y++)
  1336.                free((void *) (*user_page)[y]);
  1337.               free((void *) *user_page);
  1338.               for (y=0; y < max_y_plus_1; y++)
  1339.                free((void *) (*computer_page)[y]);
  1340.               free((void *) *computer_page);
  1341.             }
  1342.         }
  1343.       return(result);
  1344.     }
  1345.  
  1346. static void free_memory(
  1347.   char      ***computer_page,
  1348.   char      ***user_page,
  1349.   int       max_y_plus_1,
  1350.   stack_rec **stack)
  1351.     {
  1352.       register int y;
  1353.  
  1354.       free((void *) *stack);
  1355.       for (y=0; y < max_y_plus_1; y++)
  1356.         free((void *) (*user_page)[y]);
  1357.       free((void *) *user_page);
  1358.       for (y=0; y < max_y_plus_1; y++)
  1359.         free((void *) (*computer_page)[y]);
  1360.       free((void *) *computer_page);
  1361.       return;
  1362.     }
  1363.  
  1364. static void get_cursor(
  1365.   unsigned char *cursor_row,
  1366.   unsigned char *cursor_column,
  1367.   unsigned char *cursor_start,
  1368.   unsigned char *cursor_stop)
  1369.     {
  1370.       static union REGS in;
  1371.       static union REGS out;
  1372.  
  1373.       in.h.ah=(unsigned char) 3;
  1374.       in.h.bh=(unsigned char) 0;
  1375.       int86(0x10,&in,&out);
  1376.       *cursor_row=out.h.dh;
  1377.       *cursor_column=out.h.dl;
  1378.       *cursor_start=out.h.ch;
  1379.       *cursor_stop=out.h.cl;
  1380.       return;
  1381.     }
  1382.  
  1383. static void set_cursor_position(
  1384.   unsigned char cursor_row,
  1385.   unsigned char cursor_column)
  1386.     {
  1387.       static union REGS in;
  1388.       static union REGS out;
  1389.  
  1390.       in.h.ah=(unsigned char) 2;
  1391.       in.h.dh=cursor_row;
  1392.       in.h.dl=cursor_column;
  1393.       int86(0x10,&in,&out);
  1394.       return;
  1395.     }
  1396.  
  1397. static void set_cursor_size(
  1398.   unsigned char cursor_start,
  1399.   unsigned char cursor_stop)
  1400.     {
  1401.       static union REGS in;
  1402.       static union REGS out;
  1403.  
  1404.       in.h.ah=(unsigned char) 1;
  1405.       in.h.ch=cursor_start;
  1406.       in.h.cl=cursor_stop;
  1407.       int86(0x10,&in,&out);
  1408.       return;
  1409.     }
  1410.  
  1411. static void titillate()
  1412.     {
  1413.       set_cursor_position(cursor_row,cursor_column);
  1414.       titillator_index++;
  1415.       if (titillator_index > 3)
  1416.         titillator_index=0;
  1417.       putchar((int) titillator[titillator_index]);
  1418.       return;
  1419.     }
  1420.  
  1421. static void solve_maze(
  1422.   stack_rec *stack,
  1423.   char      **page,
  1424.   int       *num_rooms_in_solution,
  1425.   int       *adjacency,
  1426.   int       max_x,
  1427.   int       max_y)
  1428.     {
  1429.       int delta_index;
  1430.       int passage_found;
  1431.       int stack_head;
  1432.       int x;
  1433.       int x_next;
  1434.       int y;
  1435.       int y_next;
  1436.  
  1437.       *num_rooms_in_solution=1;
  1438.       *adjacency=0;
  1439.       x=3;
  1440.       y=2;
  1441.       stack_head=-1;
  1442.       page[y][x]='S';
  1443.       do
  1444.         {
  1445.           delta_index=0;
  1446.           passage_found=FALSE;
  1447.           do
  1448.             {
  1449.               while ((delta_index < 6) && (! passage_found))
  1450.                 {
  1451.                   x_next=x+delta_x[delta_index][0];
  1452.                   y_next=y+delta_y[delta_index][0];
  1453.                   if (page[y_next][x_next] == ' ')
  1454.                     passage_found=TRUE;
  1455.                   else
  1456.                     delta_index++;
  1457.                 }
  1458.               if (! passage_found)
  1459.                 {
  1460.                   delta_index=(int) (stack[stack_head].index_1);
  1461.                   page[y][x]=' ';
  1462.                   x-=delta_x[delta_index][0];
  1463.                   y-=delta_y[delta_index][0];
  1464.                   page[y][x]=' ';
  1465.                   x-=delta_x[delta_index][0];
  1466.                   y-=delta_y[delta_index][0];
  1467.                   stack_head--;
  1468.                   delta_index++;
  1469.                 }
  1470.             }
  1471.           while (! passage_found);
  1472.           page[y_next][x_next]='S';
  1473.           x_next+=delta_x[delta_index][0];
  1474.           y_next+=delta_y[delta_index][0];
  1475.           if (y_next <= max_y)
  1476.             {
  1477.               stack_head++;
  1478.               stack[stack_head].index_1=(char) delta_index;
  1479.               page[y_next][x_next]='S';
  1480.               x=x_next;
  1481.               y=y_next;
  1482.             }
  1483.         }
  1484.       while (y_next < max_y);
  1485.       x=max_x-3;
  1486.       y=max_y-2;
  1487.       *adjacency=0;
  1488.       while (stack_head >= 0)
  1489.         {
  1490.           for (delta_index=0; delta_index < 6; delta_index++)
  1491.             {
  1492.               x_next=x+delta_x[delta_index][0];
  1493.               y_next=y+delta_y[delta_index][0];
  1494.               if (page[y_next][x_next] != 'S')
  1495.                 {
  1496.                   if (page[y_next][x_next] == 'W')
  1497.                     {
  1498.                       x_next+=delta_x[delta_index][0];
  1499.                       y_next+=delta_y[delta_index][0];
  1500.                       if (x_next < 0)
  1501.                         (*adjacency)++;
  1502.                       else
  1503.                         if (x_next > max_x)
  1504.                           (*adjacency)++;
  1505.                         else
  1506.                           if (y_next < 0)
  1507.                             (*adjacency)++;
  1508.                           else
  1509.                             if (y_next > max_y)
  1510.                               (*adjacency)++;
  1511.                             else
  1512.                               {
  1513.                                 if (page[y_next][x_next] == 'S')
  1514.                                   (*adjacency)++;
  1515.                               }
  1516.                     }
  1517.                 }
  1518.             }
  1519.           x-=(2*delta_x[stack[stack_head].index_1][0]);
  1520.           y-=(2*delta_y[stack[stack_head].index_1][0]);
  1521.           stack_head--;
  1522.           (*num_rooms_in_solution)++;
  1523.         }
  1524.       for (delta_index=0; delta_index < 6; delta_index++)
  1525.         {
  1526.           x_next=x+delta_x[delta_index][0];
  1527.           y_next=y+delta_y[delta_index][0];
  1528.           if (page[y_next][x_next] != ' ')
  1529.             {
  1530.               if (page[y_next][x_next] == 'W')
  1531.                 {
  1532.                   x_next+=delta_x[delta_index][0];
  1533.                   y_next+=delta_y[delta_index][0];
  1534.                   if (x_next < 0)
  1535.                     (*adjacency)++;
  1536.                   else
  1537.                     if (x_next > max_x)
  1538.                       (*adjacency)++;
  1539.                     else
  1540.                       if (y_next < 0)
  1541.                         (*adjacency)++;
  1542.                       else
  1543.                         if (y_next > max_y)
  1544.                           (*adjacency)++;
  1545.                         else
  1546.                           {
  1547.                             if (page[y_next][x_next] == 'S')
  1548.                               (*adjacency)++;
  1549.                           }
  1550.                 }
  1551.             }
  1552.         }
  1553.       return;
  1554.     }
  1555.  
  1556. static void generate_maze(
  1557.   char      *seed_ptr,
  1558.   char      **page,
  1559.   int       max_x,
  1560.   int       max_y,
  1561.   stack_rec *stack,
  1562.   int       num_rooms_in_maze,
  1563.   int       num_columns,
  1564.   int       num_rows)
  1565.     {
  1566.       static   int  adjacency;
  1567.       static   int  age;
  1568.       static   int  column_num;
  1569.       static   int  counter_0;
  1570.       static   int  counter_1;
  1571.       static   int  counter_2;
  1572.       static   int  counter_3;
  1573.       static   int  counter_4;
  1574.       static   int  counter_5;
  1575.       static   int  counter_6;
  1576.       static   int  counter_7;
  1577.       static   int  delta_index_1a;
  1578.       static   int  delta_index_1b;
  1579.       static   int  delta_index_1c;
  1580.       static   int  delta_index_1d;
  1581.       static   int  delta_index_1e;
  1582.       static   int  delta_index_1f;
  1583.       static   int  delta_index_2;
  1584.       static   int  num_rooms_in_solution;
  1585.       static   int  passage_found;
  1586.       static   int  r_n [8];
  1587.       register int  r_n_index_1;
  1588.       register int  r_n_index_2;
  1589.       static   int  row_num;
  1590.       static   int  search_complete;
  1591.       static   int  stack_head;
  1592.       static   int  tem_int;
  1593.       static   int  trial_num_mod_10;
  1594.       static   int  x;
  1595.       static   int  x_mod_8;
  1596.       static   int  x_next;
  1597.       static   int  y;
  1598.       static   int  y_mod_4;
  1599.       static   int  y_next;
  1600.  
  1601.       while ((*seed_ptr == ' ')
  1602.       ||     (*seed_ptr == (char) 9))
  1603.         seed_ptr++;
  1604.       r_n_index_1=0;
  1605.       while ((r_n_index_1 < 8) && (*seed_ptr) && (*seed_ptr != '\n'))
  1606.         r_n[r_n_index_1++]=(int) (*(seed_ptr++) % 10);
  1607.       r_n_index_2=7;
  1608.       while (r_n_index_1 > 0)
  1609.         {
  1610.            r_n_index_1--;
  1611.            r_n[r_n_index_2]=r_n[r_n_index_1];
  1612.            r_n_index_2--;
  1613.         }
  1614.       while (r_n_index_2 >= 0)
  1615.         {
  1616.           r_n[r_n_index_2]=8;
  1617.           r_n_index_2--;
  1618.         }
  1619.       counter_0=r_n[0];
  1620.       counter_1=r_n[1];
  1621.       counter_2=r_n[2];
  1622.       counter_3=r_n[3];
  1623.       counter_4=r_n[4];
  1624.       counter_5=r_n[5];
  1625.       counter_6=r_n[6];
  1626.       counter_7=r_n[7];
  1627.       hash(&counter_0,&counter_1,&counter_2,&counter_3,&counter_4,&counter_5,
  1628.        &counter_6,&counter_7);
  1629.       delta_y[0][0]=-1;
  1630.       delta_x[0][0]=-2;
  1631.       delta_y[1][0]=1;
  1632.       delta_x[1][0]=-2;
  1633.       delta_y[2][0]=-2;
  1634.       delta_x[2][0]=0;
  1635.       delta_y[3][0]=2;
  1636.       delta_x[3][0]=0;
  1637.       delta_y[4][0]=-1;
  1638.       delta_x[4][0]=2;
  1639.       delta_y[5][0]=1;
  1640.       delta_x[5][0]=2;
  1641.       delta_index_2=0;
  1642.       for (delta_index_1a=0; delta_index_1a < 6; delta_index_1a++)
  1643.         for (delta_index_1b=0; delta_index_1b < 6; delta_index_1b++)
  1644.           if (delta_index_1a != delta_index_1b)
  1645.            for (delta_index_1c=0; delta_index_1c < 6; delta_index_1c++)
  1646.              if ((delta_index_1a != delta_index_1c)
  1647.              &&  (delta_index_1b != delta_index_1c))
  1648.                for (delta_index_1d=0; delta_index_1d < 6; delta_index_1d++)
  1649.                   if ((delta_index_1a != delta_index_1d)
  1650.                   &&  (delta_index_1b != delta_index_1d)
  1651.                   &&  (delta_index_1c != delta_index_1d))
  1652.                     for (delta_index_1e=0; delta_index_1e < 6;
  1653.                      delta_index_1e++)
  1654.                       if ((delta_index_1a != delta_index_1e)
  1655.                       &&  (delta_index_1b != delta_index_1e)
  1656.                       &&  (delta_index_1c != delta_index_1e)
  1657.                       &&  (delta_index_1d != delta_index_1e))
  1658.                         for (delta_index_1f=0; delta_index_1f < 6;
  1659.                          delta_index_1f++)
  1660.                           if ((delta_index_1a != delta_index_1f)
  1661.                           &&  (delta_index_1b != delta_index_1f)
  1662.                           &&  (delta_index_1c != delta_index_1f)
  1663.                           &&  (delta_index_1d != delta_index_1f)
  1664.                           &&  (delta_index_1e != delta_index_1f))
  1665.                             {
  1666.                               delta_x[delta_index_1a][delta_index_2]
  1667.                                =delta_x[0][0];
  1668.                               delta_y[delta_index_1a][delta_index_2]
  1669.                                =delta_y[0][0];
  1670.                               delta_x[delta_index_1b][delta_index_2]
  1671.                                =delta_x[1][0];
  1672.                               delta_y[delta_index_1b][delta_index_2]
  1673.                                =delta_y[1][0];
  1674.                               delta_x[delta_index_1c][delta_index_2]
  1675.                                =delta_x[2][0];
  1676.                               delta_y[delta_index_1c][delta_index_2]
  1677.                                =delta_y[2][0];
  1678.                               delta_x[delta_index_1d][delta_index_2]
  1679.                                =delta_x[3][0];
  1680.                               delta_y[delta_index_1d][delta_index_2]
  1681.                                =delta_y[3][0];
  1682.                               delta_x[delta_index_1e][delta_index_2]
  1683.                                =delta_x[4][0];
  1684.                               delta_y[delta_index_1e][delta_index_2]
  1685.                                =delta_y[4][0];
  1686.                               delta_x[delta_index_1f][delta_index_2]
  1687.                                =delta_x[5][0];
  1688.                               delta_y[delta_index_1f][delta_index_2]
  1689.                                =delta_y[5][0];
  1690.                               delta_index_2++;
  1691.                             };
  1692.       get_cursor(&cursor_row,&cursor_column,&cursor_start,&cursor_stop);
  1693.       set_cursor_size((unsigned char) 32,(unsigned char) 32);
  1694.       titillator_index=0;
  1695.       age=3;
  1696.       trial_num_mod_10=0;
  1697.       do
  1698.         {
  1699.           titillate();
  1700.           r_n[0]=counter_0+1;
  1701.           r_n[1]=counter_1+1;
  1702.           r_n[2]=counter_2+1;
  1703.           r_n[3]=counter_3+1;
  1704.           r_n[4]=counter_4+1;
  1705.           r_n[5]=counter_5+1;
  1706.           r_n[6]=counter_6+1;
  1707.           r_n[7]=counter_7+1;
  1708.           y_mod_4=1;
  1709.           for (y=0; y <= max_y; y++)
  1710.             {
  1711.               if (y_mod_4 == 1)
  1712.                 {
  1713.                   x_mod_8=1;
  1714.                   for (x=0; x <= max_x; x++)
  1715.                     {
  1716.                       if (((x_mod_8 == 0)
  1717.                         && (y != 0)
  1718.                         && (y != max_y))
  1719.                       ||  (x_mod_8 == 3)
  1720.                       ||  (x_mod_8 == 4)
  1721.                       ||  (x_mod_8 == 5))
  1722.                         page[y][x]='W';
  1723.                       else
  1724.                         page[y][x]=' ';
  1725.                       x_mod_8++;
  1726.                       if (x_mod_8 >= 8)
  1727.                         x_mod_8=0;
  1728.                     }
  1729.                 }
  1730.               else
  1731.                 {
  1732.                   if (y_mod_4 == 0 || y_mod_4 == 2)
  1733.                     {
  1734.                       x_mod_8=1;
  1735.                       for (x=0; x <= max_x; x++)
  1736.                         {
  1737.                           if ((x_mod_8 == 2) || (x_mod_8 == 6))
  1738.                             page[y][x]='W';
  1739.                           else
  1740.                             page[y][x]=' ';
  1741.                           x_mod_8++;
  1742.                           if (x_mod_8 >= 8)
  1743.                             x_mod_8=0;
  1744.                         }
  1745.                     }
  1746.                   else
  1747.                     {
  1748.                       x_mod_8=1;
  1749.                       for (x=0; x <= max_x; x++)
  1750.                         {
  1751.                           if ((x_mod_8 == 0)
  1752.                           ||  (x_mod_8 == 1)
  1753.                           ||  (x_mod_8 == 4)
  1754.                           ||  (x_mod_8 == 7))
  1755.                             page[y][x]='W';
  1756.                           else
  1757.                             page[y][x]=' ';
  1758.                           x_mod_8++;
  1759.                           if (x_mod_8 >= 8)
  1760.                             x_mod_8=0;
  1761.                       }
  1762.                     }
  1763.                 }
  1764.               y_mod_4++;
  1765.               if (y_mod_4 >= 4)
  1766.                 y_mod_4=0;
  1767.             }
  1768.           column_num=r_n[0];
  1769.           r_n_index_1=0;
  1770.           r_n_index_2=1;
  1771.           while (r_n_index_2 < 8)
  1772.             {
  1773.               tem_int=r_n[r_n_index_2];
  1774.               r_n[r_n_index_1]=tem_int;
  1775.               column_num+=tem_int;
  1776.               if (column_num >= 727)
  1777.                 column_num-=727;
  1778.               r_n_index_1=r_n_index_2;
  1779.               r_n_index_2++;
  1780.             }
  1781.           r_n[7]=column_num;
  1782.           column_num%=num_columns;
  1783.           x=4*column_num+3;
  1784.           row_num=r_n[0];
  1785.           r_n_index_1=0;
  1786.           r_n_index_2=1;
  1787.           while (r_n_index_2 < 8)
  1788.             {
  1789.               tem_int=r_n[r_n_index_2];
  1790.               r_n[r_n_index_1]=tem_int;
  1791.               row_num+=tem_int;
  1792.               if (row_num >= 727)
  1793.                 row_num-=727;
  1794.               r_n_index_1=r_n_index_2;
  1795.               r_n_index_2++;
  1796.             }
  1797.           r_n[7]=row_num;
  1798.           if (column_num%2)
  1799.             {
  1800.               row_num%=(num_rows-1);
  1801.               y=4*row_num+4;
  1802.             }
  1803.           else
  1804.             {
  1805.               row_num%=num_rows;
  1806.               y=4*row_num+2;
  1807.             }
  1808.           page[y][x]=' ';
  1809.           stack_head=-1;
  1810.           do
  1811.             {
  1812.               delta_index_1a=0;
  1813.               do
  1814.                 {
  1815.                   delta_index_2=r_n[0];
  1816.                   r_n_index_1=0;
  1817.                   r_n_index_2=1;
  1818.                   while (r_n_index_2 < 8)
  1819.                     {
  1820.                       tem_int=r_n[r_n_index_2];
  1821.                       r_n[r_n_index_1]=tem_int;
  1822.                       delta_index_2+=tem_int;
  1823.                       if (delta_index_2 >= 727)
  1824.                         delta_index_2-=727;
  1825.                       r_n_index_1=r_n_index_2;
  1826.                       r_n_index_2++;
  1827.                     }
  1828.                   r_n[7]=delta_index_2;
  1829.                 }
  1830.               while (delta_index_2 >= 720);
  1831.               passage_found=FALSE;
  1832.               search_complete=FALSE;
  1833.               while (! search_complete)
  1834.                 {
  1835.                   while ((delta_index_1a < 6) && (! passage_found))
  1836.                     {
  1837.                       x_next=x+2*delta_x[delta_index_1a][delta_index_2];
  1838.                       if (x_next <= 0)
  1839.                         delta_index_1a++;
  1840.                       else
  1841.                         if (x_next > max_x)
  1842.                           delta_index_1a++;
  1843.                         else
  1844.                           {
  1845.                             y_next=y+2*delta_y[delta_index_1a][delta_index_2];
  1846.                             if (y_next <= 0)
  1847.                               delta_index_1a++;
  1848.                             else
  1849.                               if (y_next > max_y)
  1850.                                 delta_index_1a++;
  1851.                               else
  1852.                                 if (page[y_next][x_next] == 'W')
  1853.                                   passage_found=TRUE;
  1854.                                 else
  1855.                                   delta_index_1a++;
  1856.                           }
  1857.                     }
  1858.                   if (! passage_found)
  1859.                     {
  1860.                       if (stack_head >= 0)
  1861.                         {
  1862.                           delta_index_1a=(int) (stack[stack_head].index_1);
  1863.                           delta_index_2=stack[stack_head].index_2;
  1864.                           x-=2*delta_x[delta_index_1a][delta_index_2];
  1865.                           y-=2*delta_y[delta_index_1a][delta_index_2];
  1866.                           stack_head--;
  1867.                           delta_index_1a++;
  1868.                         }
  1869.                     }
  1870.                   search_complete=((passage_found)
  1871.                    || ((stack_head == -1) && (delta_index_1a >= 6)));
  1872.                 }
  1873.               if (passage_found)
  1874.                 {
  1875.                   stack_head++;
  1876.                   stack[stack_head].index_1=(char) delta_index_1a;
  1877.                   stack[stack_head].index_2=delta_index_2;
  1878.                   page[y_next][x_next]=' ';
  1879.                   page[(y+y_next)/2][(x+x_next)/2]=' ';
  1880.                   x=x_next;
  1881.                   y=y_next;
  1882.                 }
  1883.             }
  1884.           while (stack_head != -1);
  1885.           page[0][3]='S';
  1886.           page[max_y][max_x-3]=' ';
  1887.           solve_maze(stack,page,&num_rooms_in_solution,&adjacency,max_x,
  1888.            max_y);
  1889.           increment(&counter_0,&counter_1,&counter_2,&counter_3,&counter_4,
  1890.            &counter_5,&counter_6,&counter_7);
  1891.           trial_num_mod_10++;
  1892.           if (trial_num_mod_10 >= 10)
  1893.             {
  1894.               trial_num_mod_10=0;
  1895.               age++;
  1896.             }
  1897.         }
  1898.       while ((3*num_rooms_in_solution < num_rooms_in_maze)
  1899.       ||     (2*adjacency > age*num_rooms_in_solution));
  1900.       return;
  1901.     }
  1902.  
  1903. static int substitution_high [100] =
  1904.              { 4,1,2,8,8,9,9,6,5,7,2,1,2,9,8,8,6,3,5,1,9,5,4,4,9,8,6,0,8,0,
  1905.                6,0,2,4,1,9,2,0,7,4,7,3,0,0,2,6,8,9,4,0,8,3,2,3,2,5,2,4,6,9,
  1906.                7,9,1,3,5,7,1,1,4,5,8,1,6,0,5,7,8,2,3,3,7,3,5,1,7,5,4,0,3,6,
  1907.                3,7,7,1,9,4,0,5,6,6
  1908.              };
  1909. static int substitution_low [100] =
  1910.              { 1,2,2,1,5,5,4,6,4,6,4,4,5,6,6,3,0,9,6,5,7,2,0,9,3,4,2,3,9,1,
  1911.                9,9,9,3,8,9,3,4,1,5,0,5,2,7,0,8,8,0,4,5,0,3,6,8,1,7,8,8,7,1,
  1912.                3,2,7,7,1,8,0,3,7,5,2,6,4,0,9,9,7,7,4,6,2,0,0,1,7,3,6,6,1,1,
  1913.                2,4,5,9,8,2,8,8,3,5
  1914.              };
  1915. static void hash(
  1916.   int *counter_0,
  1917.   int *counter_1,
  1918.   int *counter_2,
  1919.   int *counter_3,
  1920.   int *counter_4,
  1921.   int *counter_5,
  1922.   int *counter_6,
  1923.   int *counter_7)
  1924.     {
  1925.       register int iteration;
  1926.       static   int seed_0;
  1927.       static   int seed_1;
  1928.       static   int seed_2;
  1929.       static   int seed_3;
  1930.       static   int seed_4;
  1931.       static   int seed_5;
  1932.       static   int seed_6;
  1933.       static   int seed_7;
  1934.       register int substitution_index;
  1935.       static   int tem_0;
  1936.       static   int tem_1;
  1937.       static   int tem_2;
  1938.  
  1939.       seed_0=(*counter_0);
  1940.       seed_1=(*counter_1);
  1941.       seed_2=(*counter_2);
  1942.       seed_3=(*counter_3);
  1943.       seed_4=(*counter_4);
  1944.       seed_5=(*counter_5);
  1945.       seed_6=(*counter_6);
  1946.       seed_7=(*counter_7);
  1947.       for (iteration=1; iteration <= 8; iteration++)
  1948.         {
  1949.           substitution_index=10*seed_1+seed_0;
  1950.           tem_0=substitution_low[substitution_index];
  1951.           tem_1=substitution_high[substitution_index];
  1952.           substitution_index=10*seed_3+seed_2;
  1953.           seed_0=substitution_low[substitution_index];
  1954.           tem_2=substitution_high[substitution_index];
  1955.           substitution_index=10*seed_5+seed_4;
  1956.           seed_2=substitution_low[substitution_index];
  1957.           seed_1=substitution_high[substitution_index];
  1958.           substitution_index=10*seed_7+seed_6;
  1959.           seed_5=substitution_low[substitution_index];
  1960.           seed_7=substitution_high[substitution_index];
  1961.           seed_3=tem_0;
  1962.           seed_6=tem_1;
  1963.           seed_4=tem_2;
  1964.         }
  1965.       (*counter_0)=seed_0;
  1966.       (*counter_1)=seed_1;
  1967.       (*counter_2)=seed_2;
  1968.       (*counter_3)=seed_3;
  1969.       (*counter_4)=seed_4;
  1970.       (*counter_5)=seed_5;
  1971.       (*counter_6)=seed_6;
  1972.       (*counter_7)=seed_7;
  1973.       return;
  1974.     }
  1975.  
  1976. static void increment(
  1977.   int *counter_0,
  1978.   int *counter_1,
  1979.   int *counter_2,
  1980.   int *counter_3,
  1981.   int *counter_4,
  1982.   int *counter_5,
  1983.   int *counter_6,
  1984.   int *counter_7)
  1985.     {
  1986.       register tem;
  1987.  
  1988.       tem=(*counter_0)+1;
  1989.       if (tem <= 9)
  1990.         (*counter_0)=tem;
  1991.       else
  1992.         {
  1993.           (*counter_0)=0;
  1994.           tem=(*counter_1)+1;
  1995.           if (tem <= 9)
  1996.             (*counter_1)=tem;
  1997.           else
  1998.             {
  1999.               (*counter_1)=0;
  2000.               tem=(*counter_2)+1;
  2001.               if (tem <= 9)
  2002.                 (*counter_2)=tem;
  2003.               else
  2004.                 {
  2005.                   (*counter_2)=0;
  2006.                   tem=(*counter_3)+1;
  2007.                   if (tem <= 9)
  2008.                     (*counter_3)=tem;
  2009.                   else
  2010.                     {
  2011.                       (*counter_3)=0;
  2012.                       tem=(*counter_4)+1;
  2013.                       if (tem <= 9)
  2014.                         (*counter_4)=tem;
  2015.                       else
  2016.                         {
  2017.                           (*counter_4)=0;
  2018.                           tem=(*counter_5)+1;
  2019.                           if (tem <= 9)
  2020.                             (*counter_5)=tem;
  2021.                           else
  2022.                             {
  2023.                               (*counter_5)=0;
  2024.                               tem=(*counter_6)+1;
  2025.                               if (tem <= 9)
  2026.                                 (*counter_6)=tem;
  2027.                               else
  2028.                                 {
  2029.                                   (*counter_6)=0;
  2030.                                   tem=(*counter_7)+1;
  2031.                                   if (tem <= 9)
  2032.                                     (*counter_7)=tem;
  2033.                                   else
  2034.                                     (*counter_7)=0;
  2035.                                 }
  2036.                             }
  2037.                         }
  2038.                     }
  2039.                 }
  2040.             }
  2041.         }
  2042.       return;
  2043.     }
  2044.  
  2045. static void draw_line(
  2046.   double x1,
  2047.   double y1,
  2048.   double x2,
  2049.   double y2,
  2050.   double x_max,
  2051.   double x_offset,
  2052.   double y_max,
  2053.   double cos_tilt,
  2054.   double sin_tilt,
  2055.   double pixels_per_x,
  2056.   double pixels_per_z,
  2057.   double rel_dist_of_user_from_screen)
  2058.     {
  2059.       static corner_rec end_point [2];
  2060.  
  2061.       get_corner(x1,y1,RELATIVE_HEIGHT_OF_WALL,pixels_per_x,pixels_per_z,
  2062.        cos_tilt,sin_tilt,rel_dist_of_user_from_screen,x_max,x_offset,y_max,
  2063.        &end_point[0]);
  2064.       get_corner(x2,y2,RELATIVE_HEIGHT_OF_WALL,pixels_per_x,pixels_per_z,
  2065.        cos_tilt,sin_tilt,rel_dist_of_user_from_screen,x_max,x_offset,y_max,
  2066.        &end_point[1]);
  2067.       moveto(end_point[0].x,end_point[0].y);
  2068.       lineto(end_point[1].x,end_point[1].y);
  2069.       return;
  2070.     }
  2071.  
  2072. static void display_solution(
  2073.   int    max_y,
  2074.   char   **page,
  2075.   double x_max,
  2076.   double x_offset,
  2077.   double y_max,
  2078.   double cos_tilt,
  2079.   double sin_tilt,
  2080.   double pixels_per_x,
  2081.   double pixels_per_z,
  2082.   double rel_dist_of_user_from_screen)
  2083.     {
  2084.       static int    delta_index;
  2085.       static int    path_found;
  2086.       static int    x;
  2087.       static int    x_next;
  2088.       static int    x_previous;
  2089.       static double x_relative;
  2090.       static double x_relative_next;
  2091.       static int    y;
  2092.       static int    y_next;
  2093.       static int    y_previous;
  2094.       static double y_relative;
  2095.       static double y_relative_next;
  2096.  
  2097.       setlinestyle(SOLID_LINE,0xffff,THICK_WIDTH);
  2098.       setcolor(SOLUTION_COLOR);
  2099.       x_relative=1.0;
  2100.       y_relative=sqrt_3/2.0;
  2101.       draw_line(1.0,0.0,x_relative,y_relative,x_max,x_offset,y_max,cos_tilt,
  2102.        sin_tilt,pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
  2103.       x_previous=3;
  2104.       y_previous=-2;
  2105.       x=3;
  2106.       y=2;
  2107.       do
  2108.         {
  2109.           path_found=FALSE;
  2110.           delta_index=0;
  2111.           while (! path_found)
  2112.             {
  2113.               x_next=x+delta_x[delta_index][0];
  2114.               y_next=y+delta_y[delta_index][0];
  2115.               if (page[y_next][x_next] == 'S')
  2116.                 {
  2117.                   x_next+=delta_x[delta_index][0];
  2118.                   y_next+=delta_y[delta_index][0];
  2119.                   if ((x_next != x_previous) || (y_next != y_previous))
  2120.                     path_found=TRUE;
  2121.                   else
  2122.                     delta_index++;
  2123.                 }
  2124.               else
  2125.                 delta_index++;
  2126.             }
  2127.           if (y_next < max_y)
  2128.             {
  2129.               switch (y_next-y)
  2130.                 {
  2131.                   case -4:
  2132.                     x_relative_next=x_relative;
  2133.                     y_relative_next=y_relative-sqrt_3;
  2134.                     break;
  2135.                   case -2:
  2136.                     if (x_next > x)
  2137.                       {
  2138.                         x_relative_next=x_relative+3.0/2.0;
  2139.                         y_relative_next=y_relative-sqrt_3/2.0;
  2140.                       }
  2141.                     else
  2142.                       {
  2143.                         x_relative_next=x_relative-3.0/2.0;
  2144.                         y_relative_next=y_relative-sqrt_3/2.0;
  2145.                       }
  2146.                     break;
  2147.                   case 2:
  2148.                     if (x_next > x)
  2149.                       {
  2150.                         x_relative_next=x_relative+3.0/2.0;
  2151.                         y_relative_next=y_relative+sqrt_3/2.0;
  2152.                       }
  2153.                     else
  2154.                       {
  2155.                         x_relative_next=x_relative-3.0/2.0;
  2156.                         y_relative_next=y_relative+sqrt_3/2.0;
  2157.                       }
  2158.                     break;
  2159.                   default:
  2160.                     x_relative_next=x_relative;
  2161.                     y_relative_next=y_relative+sqrt_3;
  2162.                     break;
  2163.                 }
  2164.               draw_line(x_relative,y_relative,x_relative_next,
  2165.                y_relative_next,x_max,x_offset,y_max,cos_tilt,sin_tilt,
  2166.                pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
  2167.             }
  2168.           else
  2169.             draw_line(x_relative,y_relative,x_max-1.0,y_max,x_max,x_offset,
  2170.              y_max,cos_tilt,sin_tilt,pixels_per_x,pixels_per_z,
  2171.              rel_dist_of_user_from_screen);
  2172.           x_previous=x;
  2173.           y_previous=y;
  2174.           x=x_next;
  2175.           y=y_next;
  2176.           x_relative=x_relative_next;
  2177.           y_relative=y_relative_next;
  2178.         }
  2179.       while (y_next < max_y);
  2180.       return;
  2181.     }
  2182.  
  2183. static void let_user_try_to_solve(
  2184.   int    *key_pressed,
  2185.   int    max_x,
  2186.   int    max_y,
  2187.   char   **computer_page,
  2188.   char   **user_page,
  2189.   double x_max,
  2190.   double x_offset,
  2191.   double y_max,
  2192.   double cos_tilt,
  2193.   double sin_tilt,
  2194.   double pixels_per_x,
  2195.   double pixels_per_z,
  2196.   double rel_dist_of_user_from_screen)
  2197.     {
  2198.       static int    delta_index_1;
  2199.       static int    frequency;
  2200.       static int    passage_found;
  2201.       static int    x;
  2202.       static int    x_next;
  2203.       static double x_relative;
  2204.       static double x_relative_next;
  2205.       static int    y;
  2206.       static int    y_next;
  2207.       static double y_relative;
  2208.       static double y_relative_next;
  2209.  
  2210.       setlinestyle(SOLID_LINE,0xffff,NORM_WIDTH);
  2211.       for (x=0; x <= max_x; x++)
  2212.         for (y=0; y <= max_y; y++)
  2213.           if (computer_page[y][x] == 'W')
  2214.             user_page[y][x]='W';
  2215.           else
  2216.             user_page[y][x]=' ';
  2217.       x=3;
  2218.       y=2;
  2219.       user_page[y][x]='S';
  2220.       x_relative=1.0;
  2221.       y_relative=sqrt_3/2.0;
  2222.       setcolor(ADVANCE_COLOR);
  2223.       draw_line(1.0,0.0,x_relative,y_relative,x_max,x_offset,y_max,cos_tilt,
  2224.        sin_tilt,pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
  2225.       do
  2226.         {
  2227.           do
  2228.             {
  2229.               passage_found=TRUE;
  2230.               *key_pressed=getch();
  2231.               if ((*key_pressed != (int) 'Q')
  2232.               &&  (*key_pressed != (int) 'q')
  2233.               &&  (*key_pressed != (int) 'S')
  2234.               &&  (*key_pressed != (int) 's'))
  2235.                 {
  2236.                   if (*key_pressed == 0)
  2237.                     {
  2238.                       *key_pressed=getch();
  2239.                       switch (*key_pressed)
  2240.                         {
  2241.                           case 71:
  2242.                              delta_index_1=0;
  2243.                              break;
  2244.                           case 72:
  2245.                              delta_index_1=2;
  2246.                              break;
  2247.                           case 73:
  2248.                              delta_index_1=4;
  2249.                              break;
  2250.                           case 79:
  2251.                              delta_index_1=1;
  2252.                              break;
  2253.                           case 80:
  2254.                              delta_index_1=3;
  2255.                              break;
  2256.                           case 81:
  2257.                              delta_index_1=5;
  2258.                              break;
  2259.                           default:
  2260.                             {
  2261.                               passage_found=FALSE;
  2262.                               sound(120);
  2263.                               delay(278);
  2264.                               nosound();
  2265.                               break;
  2266.                             }
  2267.                         }
  2268.                       *key_pressed=0;
  2269.                     }
  2270.                   else
  2271.                     {
  2272.                       switch (*key_pressed)
  2273.                         {
  2274.                           case 49:
  2275.                             delta_index_1=1;
  2276.                             break;
  2277.                           case 50:
  2278.                             delta_index_1=3;
  2279.                             break;
  2280.                           case 51:
  2281.                             delta_index_1=5;
  2282.                             break;
  2283.                           case 55:
  2284.                             delta_index_1=0;
  2285.                             break;
  2286.                           case 56:
  2287.                             delta_index_1=2;
  2288.                             break;
  2289.                           case 57:
  2290.                             delta_index_1=4;
  2291.                             break;
  2292.                           default:
  2293.                             passage_found=FALSE;
  2294.                             break;
  2295.                         }
  2296.                     }
  2297.                   if (passage_found)
  2298.                     {
  2299.                       x_next=x+delta_x[delta_index_1][0];
  2300.                       if (x_next <= 0)
  2301.                         passage_found=FALSE;
  2302.                       else
  2303.                         if (x_next >= max_x)
  2304.                           passage_found=FALSE;
  2305.                         else
  2306.                           {
  2307.                             y_next=y+delta_y[delta_index_1][0];
  2308.                             if (y_next <= 0)
  2309.                               passage_found=FALSE;
  2310.                             else
  2311.                               if (y_next > max_y)
  2312.                                 passage_found=FALSE;
  2313.                               else
  2314.                                 if (user_page[y_next][x_next] == 'W')
  2315.                                   passage_found=FALSE;
  2316.                           }
  2317.                     }
  2318.                   if (! passage_found)
  2319.                     {
  2320.                       passage_found=FALSE;
  2321.                       sound(120);
  2322.                       delay(278);
  2323.                       nosound();
  2324.                     }
  2325.                 }
  2326.             }
  2327.           while ((! passage_found)
  2328.           &&     (*key_pressed != (int) 'Q')
  2329.           &&     (*key_pressed != (int) 'q')
  2330.           &&     (*key_pressed != (int) 'S')
  2331.           &&     (*key_pressed != (int) 's'));
  2332.           if ((*key_pressed != (int) 'Q')
  2333.           &&  (*key_pressed != (int) 'q')
  2334.           &&  (*key_pressed != (int) 'S')
  2335.           &&  (*key_pressed != (int) 's'))
  2336.             {
  2337.               x_next+=delta_x[delta_index_1][0];
  2338.               y_next+=delta_y[delta_index_1][0];
  2339.               if (y_next < max_y)
  2340.                 {
  2341.                   if (user_page[y_next][x_next] == 'S')
  2342.                     {
  2343.                       setcolor(BACKOUT_COLOR);
  2344.                       user_page[y][x]=' ';
  2345.                     }
  2346.                   else
  2347.                     {
  2348.                       setcolor(ADVANCE_COLOR);
  2349.                       user_page[y_next][x_next]='S';
  2350.                     }
  2351.                   switch (y_next-y)
  2352.                     {
  2353.                       case -4:
  2354.                         x_relative_next=x_relative;
  2355.                         y_relative_next=y_relative-sqrt_3;
  2356.                         break;
  2357.                       case -2:
  2358.                         if (x_next > x)
  2359.                           {
  2360.                             x_relative_next=x_relative+3.0/2.0;
  2361.                             y_relative_next=y_relative-sqrt_3/2.0;
  2362.                           }
  2363.                         else
  2364.                           {
  2365.                             x_relative_next=x_relative-3.0/2.0;
  2366.                             y_relative_next=y_relative-sqrt_3/2.0;
  2367.                           }
  2368.                         break;
  2369.                       case 2:
  2370.                         if (x_next > x)
  2371.                           {
  2372.                             x_relative_next=x_relative+3.0/2.0;
  2373.                             y_relative_next=y_relative+sqrt_3/2.0;
  2374.                           }
  2375.                         else
  2376.                           {
  2377.                             x_relative_next=x_relative-3.0/2.0;
  2378.                             y_relative_next=y_relative+sqrt_3/2.0;
  2379.                           }
  2380.                         break;
  2381.                       default:
  2382.                         x_relative_next=x_relative;
  2383.                         y_relative_next=y_relative+sqrt_3;
  2384.                         break;
  2385.                     }
  2386.                   draw_line(x_relative,y_relative,x_relative_next,
  2387.                    y_relative_next,x_max,x_offset,y_max,cos_tilt,sin_tilt,
  2388.                    pixels_per_x,pixels_per_z,rel_dist_of_user_from_screen);
  2389.                 }
  2390.               else
  2391.                 {
  2392.                   setcolor(ADVANCE_COLOR);
  2393.                   draw_line(x_relative,y_relative,x_max-1.0,y_max,
  2394.                    x_max,x_offset,y_max,cos_tilt,sin_tilt,pixels_per_x,
  2395.                    pixels_per_z,rel_dist_of_user_from_screen);
  2396.                 }
  2397.               x=x_next;
  2398.               y=y_next;
  2399.               x_relative=x_relative_next;
  2400.               y_relative=y_relative_next;
  2401.             }
  2402.         }
  2403.       while ((y_next < max_y)
  2404.       &&     (*key_pressed != (int) 'Q')
  2405.       &&     (*key_pressed != (int) 'q')
  2406.       &&     (*key_pressed != (int) 'S')
  2407.       &&     (*key_pressed != (int) 's'));
  2408.       setcolor(0);
  2409.       outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  2410.        "Home PgUp PgDn End \030 \031 - Move    S - Solve    Q - Quit");
  2411.       if    ((*key_pressed != (int) 'Q')
  2412.       &&     (*key_pressed != (int) 'q')
  2413.       &&     (*key_pressed != (int) 'S')
  2414.       &&     (*key_pressed != (int) 's'))
  2415.         {
  2416.           setcolor(NUM_COLORS-4);
  2417.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,"Congratulations!");
  2418.           frequency=10;
  2419.           for (delta_index_1=1; delta_index_1 <= 100;
  2420.            delta_index_1++)
  2421.             {
  2422.               sound(frequency);
  2423.               delay(56);
  2424.               nosound();
  2425.               frequency+=10;
  2426.             };
  2427.           setcolor(0);
  2428.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,"Congratulations!");
  2429.           setcolor(NUM_COLORS-4);
  2430.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  2431.            "S - Solve    Other - Restart program");
  2432.           while (kbhit())
  2433.             {
  2434.               *key_pressed=getch();
  2435.               if (*key_pressed == 0)
  2436.                 {
  2437.                   *key_pressed=getch();
  2438.                   *key_pressed=(int) ' ';
  2439.                 }
  2440.             }
  2441.           *key_pressed=getch();
  2442.           if (*key_pressed == 0)
  2443.             {
  2444.               *key_pressed=getch();
  2445.               *key_pressed=(int) ' ';
  2446.             }
  2447.           setcolor(0);
  2448.           outtextxy(NUM_X_PIXELS/2,NUM_Y_PIXELS-1,
  2449.            "S - Solve    Other - Restart program");
  2450.         }
  2451.       return;
  2452.     }
  2453.